package com.ytjj.qmyx.supplychain.service;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.gson.Gson;
import com.kuaidi100.sdk.api.Subscribe;
import com.kuaidi100.sdk.contant.ApiInfoConstant;
import com.kuaidi100.sdk.core.IBaseClient;
import com.kuaidi100.sdk.enums.ExpressEnums;
import com.kuaidi100.sdk.pojo.HttpResult;
import com.kuaidi100.sdk.request.SubscribeNewReq;
import com.kuaidi100.sdk.request.SubscribeParam;
import com.kuaidi100.sdk.request.SubscribeParameters;
import com.kuaidi100.sdk.response.QueryTrackData;
import com.ytjj.qmyx.supplychain.common.api.CommonPage;
import com.ytjj.qmyx.supplychain.common.api.CommonResult;
import com.ytjj.qmyx.supplychain.common.configuration.WMSPlatformConfig;
import com.ytjj.qmyx.supplychain.common.constants.QueueConstants;
import com.ytjj.qmyx.supplychain.common.constants.RedisConstants;
import com.ytjj.qmyx.supplychain.common.enums.*;
import com.ytjj.qmyx.supplychain.common.exception.ApiException;
import com.ytjj.qmyx.supplychain.common.exception.GlobalExceptionHandler;
import com.ytjj.qmyx.supplychain.common.model.BankerOrderVO;
import com.ytjj.qmyx.supplychain.common.model.OrderResponse;
import com.ytjj.qmyx.supplychain.common.model.ProductSpecVO;
import com.ytjj.qmyx.supplychain.common.model.dto.*;
import com.ytjj.qmyx.supplychain.common.model.request.*;
import com.ytjj.qmyx.supplychain.common.model.request.link.*;
import com.ytjj.qmyx.supplychain.common.model.request.link.back.OrderExpressBack;
import com.ytjj.qmyx.supplychain.common.model.response.*;
import com.ytjj.qmyx.supplychain.common.utils.*;
import com.ytjj.qmyx.supplychain.common.utils.feishu.FeiShuUtil;
import com.ytjj.qmyx.supplychain.mapper.*;
import com.ytjj.qmyx.supplychain.mapper.entity.*;
import execute.OrderAction;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StopWatch;
import request.OrderItemsRequest;
import request.OrderPayRequest;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.alibaba.excel.EasyExcel;

@Slf4j
@Service
@RefreshScope
public class OrderService extends AbstractService<OrdersMapper, YxOrders> {
    //一个sheet装100w数据
    public static final Integer PER_SHEET_ROW_COUNT = 1000000;
    //每次查询20w数据，每次写入20w数据
    public static final Integer PER_WRITE_ROW_COUNT = 10000;
    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private OrdersPayMapper ordersPayMapper;
    @Resource
    private BankerMapper bankerMapper;
    @Resource
    private ExpressDicMapper expressDicMapper;
    @Resource
    private BankerOrderMapper bankerOrderMapper;
    @Resource
    private BankerExportRecordMapper bankerExportRecordMapper;
    @Resource
    private ExpressDicService expressDicService;
    @Resource
    private ExpressOrdersMapper expressOrdersMapper;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private ProductSpecMapper productSpecMapper;
    @Resource
    private BankerProductMapper bankerProductMapper;
    @Resource
    private ProductService productService;
    @Resource
    private BankerProductSpecMapper bankerProductSpecMapper;
    @Resource
    private ReturnGoodsMapper returnGoodsMapper;
    @Resource
    private ProductBatchRuleMapper productBatchRuleMapper;
    @Resource
    private ProductBatchPriceMapper productBatchPriceMapper;
    @Resource
    private OrderExceptionMapper orderExceptionMapper;
    @Resource
    private OrderSpecMapper orderSpecMapper;
    @Autowired
    private BankerService bankerService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private UploadOrderJstService uploadOrderJstService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private CebOrderMapper cebOrderMapper;
    @Resource
    private CebOrderGoodsinfoMapper cebOrderGoodsinfoMapper;
    @Resource
    private AbroadOrderRecordMapper abroadOrderRecordMapper;
    @Resource
    private WMSPlatformConfig wmsPlatformConfig;
    @Resource
    private OrderExceptionNoteMapper orderExceptionNoteMapper;
    @Value("${orderServicePath:}")
    private String orderServicePath;
    @Value(value = "${orderPath:}")
    private String path;
    private String jstBankerIdAll = "775,1120";//测试用
    @Value("${jushuitan.sHostUrl:}")
    private String sHostUrl;
    @Value("${wdt.bankerId:}")
    private String wdtBankerId;//接通旺店通的供应商id

    //快递100授权码
    @Value("${kuaidi100.key:xxx}")
    private String kuaidi100_key;
    //快递100订阅回调地址
    @Value("${kuaidi100.backurl:https://xxx.xxxx.cn/supplychain_api/express/callback}")
    private String kuaidi100_url;
    //快递100是否开启订阅  1-开启 0-不开启
    @Value("${kuaidi100.subscrib.switch:0}")
    private Integer kuaidi100_subscrib_switch;
    /**
     * 环境参数
     */
    @Value("${spring.profiles.active:}")
    private String active;
    //谷创2-400
    @Value("${company.tel.qm:}")
    private String companyTel_QM;
    //谷创-400
    @Value("${company.tel.gb:}")
    private String companyTel_GB;

    @Resource
    private ReturnDutyMapper returnDutyMapper;

    @Value("${qmyx.callback.host:https://admin.xxx.com/admin_api/callback/app}")
    private String callBack_host;
    @Resource
    private NotifyUrlInfoMapper notifyUrlInfoMapper;

    /**
     * 需要忽略的订单收货人
     * 多个用','分割
     */
    @Value("${ignore.order.userName:测试}")
    private String ignoreOrderUserName;
    @Resource
    private LinkErpService linkErpService;
    @Resource
    private OrderKafkaRecordMapper orderKafkaRecordMapper;
    @Resource
    private ShopInfoMapper shopInfoMapper;
    @Resource
    private ExpressRecordsMapper expressRecordsMapper;

    @Resource(name="guchuangRabbitTemplate")
    private RabbitTemplate guchuangRabbitTemplate;
//    @Resource(name = "jumaiduoRabbitTemplate")
//    private RabbitTemplate jumaiduoRabbitTemplate;
//    @Resource(name = "yiquanRabbitTemplate")
//    private RabbitTemplate yiquanRabbitTemplate;
//    @Resource(name = "zxlpRabbitTemplate")
//    private RabbitTemplate zxlpRabbitTemplate;
//    @Resource(name = "ygyxRabbitTemplate")
//    private RabbitTemplate ygyxRabbitTemplate;
//    @Resource(name = "yxhdRabbitTemplate")
//    private RabbitTemplate yxhdRabbitTemplate;
//    @Resource(name = "jckjRabbitTemplate")
//    private RabbitTemplate jckjRabbitTemplate;
    @Resource
    private ExpressOrderService expressOrderService;

    @Resource
    @Qualifier("excelThreadPool")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Resource
    private OrderExceptionService orderExceptionService;

    /**
     * 消息模板
     */
    private static final String template = "<<<%s>>> \n 【服务名】: %s(%s) \n 【状态】: %s(%s) \n 【服务ip】: %s \n 【详情】: %s";
    //跨境订单发送钉钉机器人消息token
    //关键字：跨境
    private static final String kuajing_accessToken = "67a026cf07bcbed8e5b0b933d33aef8d8711a6f3a4c1f88018f140f0f34de4d9";

    public void batchInsertOrders(List<OrdersRequest> ordersRequestList) {
        List<OrdersRequest> list = ordersRequestList.stream()
                .filter(item -> Strings.isNotEmpty(item.getOrderNo()))
                .map(item -> {
                    // 根据仓库名查询商户id
                    Integer bankerId = bankerService.queryByNameLike(item.getWarehouse()).getId();
                    item.setBankerId(bankerId);
                    item.setIsExport((byte) 0);
                    // 设置来源为 -> 人为导入
                    item.setSource((byte) 7);
                    item.setImportTime(new Date());
                    item.setOrderStatus((byte) 0);
                    item.setIsSync((byte) 0);
                    return item;
                }).collect(Collectors.toList());
        try {
            list.stream().forEach(item -> {
                YxBankerOrder bankerOrder = new YxBankerOrder();
                BeanUtils.copyProperties(item, bankerOrder);
                bankerOrderMapper.insert(bankerOrder);
            });
        } catch (DataAccessException e) {
            log.info("表格存在已导过的订单 e:{}", GlobalExceptionHandler.getExceptionToString(e));
            throw new ApiException("表格存在已导过的订单，请检查后重试");
        }
    }

    public String batchExportOrders(ExportOrdersRequest exportOrdersRequest) {
        log.info("===exportOrderRequest==={}", exportOrdersRequest);
        List<OrderResponse> responses = bankerOrderMapper.queryOrdersResponse(exportOrdersRequest);
        if (responses.size() <= 0) {
            throw new ApiException("查询数据为空，导出失败");
        }
        log.info("responses===查询数据数量为:{}",responses.size());

        if (("1,2").contains(String.valueOf(exportOrdersRequest.getStatus()))) {
            responses.stream().forEach(item -> {
//                YxBankerOrder yxBankerOrder = new YxBankerOrder();
//                BeanUtils.copyProperties(item, yxBankerOrder);
//                yxBankerOrder.setIsExport((byte) 1);
//                yxBankerOrder.setExportTime(new Date());
                bankerOrderMapper.updateOrderExportTime(item.getId());
            });

        }
        log.info("=========================1=========================");
        CountDownLatch countDownLatch1 = new CountDownLatch(responses.size());
        List<OrdersResponse> ordersResponses = responses.parallelStream().map(item -> {
                    BankerOrderVO bankerOrderVO = new BankerOrderVO();
                    BeanUtils.copyProperties(item, bankerOrderVO);
                    OrdersResponse ordersResponse = new OrdersResponse(bankerOrderVO);
                    ordersResponse.setTypeno(this.getTypeno(String.valueOf(item.getId())));
                    countDownLatch1.countDown();
                    return ordersResponse;
                }).collect(Collectors.toList());
        try {
            countDownLatch1.await();
        } catch (InterruptedException e) {
            log.error("===={}", e);
        }
        log.info("OrdersResponse==== 订单数据:{}",ordersResponses.size());
        log.info("=========================2=========================");
        CountDownLatch countDownLatch3 = new CountDownLatch(ordersResponses.size());
        List<String> childOrderNos = ordersResponses.parallelStream().map(OrdersResponse::getChildOrderNo).collect(Collectors.toList());
        Example example = new Example(YxReturnGoods.class);
        example.createCriteria().andIn("childOrderNo", childOrderNos).andNotIn("status", Arrays.asList(5,6,7));
        example.selectProperties("status", "serviceNo", "amount", "childOrderNo");
        List<YxReturnGoods> yxReturnGoods = returnGoodsMapper.selectByExample(example);
        childOrderNos = null;

        ordersResponses.stream().forEach(item -> {
            List<YxReturnGoods> matchList =
                    yxReturnGoods.parallelStream().filter(returnGoods ->
                            returnGoods.getChildOrderNo().equals(item.getChildOrderNo())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(matchList)) {
                YxReturnGoods returnGoods = matchList.get(0);
                item.setReturnGoodStatusName(ReturnGoodsStatusEnums.getStatusDesc(String.valueOf(returnGoods.getStatus())));
                item.setServiceNo(returnGoods.getServiceNo());
                item.setAmount(returnGoods.getAmount());
            }
            item.setOrderInfoStatusName(OrderStatusEnums.getStatusDesc(String.valueOf(item.getOrderInfoStatus())));
            countDownLatch3.countDown();
        });
        try {
            countDownLatch3.await();
        } catch (InterruptedException e) {
            log.error("==={}", e);
        }
        log.info("=========================3=========================");
        List<Integer> productSpecIds = responses.stream().filter(item -> null != item.getProductSpecId()).map(OrderResponse::getProductSpecId).collect(Collectors.toList());
        List<ProductSpecVO> productSpecVOS = new ArrayList<>();
        if (!CollectionUtils.isEmpty(productSpecIds)){
            productSpecVOS =  productSpecMapper.selectByProductSpecIds(productSpecIds);
        }

        log.info("=========================4=========================");
        List<List<String>> data = Collections.synchronizedList(new ArrayList<List<String>>());
        List<ProductSpecVO> finalProductSpecVOS = productSpecVOS;
        CountDownLatch countDownLatch = new CountDownLatch(responses.size());
        log.info("====counDownLatch.size()={}", responses.size());
        List<String> childOrderNoList = ordersResponses.parallelStream().map(OrdersResponse::getChildOrderNo).collect(Collectors.toList());
        List<YxExpressRecords> records = expressRecordsMapper.queryByChildOrderNoList(childOrderNoList);
        ordersResponses.parallelStream().forEach(ordersResponse -> {
                try {
                    String expressRecordStr =  records.stream().filter(record -> record.getChildOrderNo().equals(ordersResponse.getChildOrderNo()))
                            .map(record -> ExpressDicUtil.getMapKey(record.getCompanyNo()) +":"+ record.getExpressEno()).collect(Collectors.joining("/"));

                    String goodsCode = "";
                    if (!CollectionUtils.isEmpty(finalProductSpecVOS)){
                        List<ProductSpecVO> collect = finalProductSpecVOS.stream().filter(item -> null != ordersResponse.getProductSpecId() && item.getId().equals(ordersResponse.getProductSpecId())).collect(Collectors.toList());
                        if (!CollectionUtils.isEmpty(collect)){
                            goodsCode =  collect.get(0).getGoodsCode();
                        }
                    }
                    List<String> row = new ArrayList<>();
                    row.add(ordersResponse.getId().toString());
                    row.add(ordersResponse.getChildOrderNo());
                    row.add(ordersResponse.getCreateTimeText());
                    row.add(ordersResponse.getOrderInfoStatusName());
                    row.add(ordersResponse.getProductName());
                    row.add(ordersResponse.getTopCategoryTitle());
                    row.add(ordersResponse.getCategoryTitle());
                    row.add(ordersResponse.getBottomCategoryTitle());
                    //是否测评订单
//                    row.add(null != ordersResponse.getIsZeroProduct() && ordersResponse.getIsZeroProduct() == 1 ? "是" : "不是");
                    row.add(ordersResponse.getProductSkuSpec());
                    row.add(goodsCode);
                    row.add(ordersResponse.getThreeSkuId());
                    row.add(ordersResponse.getProductSum().toString());
                    row.add(ordersResponse.getTypeno());
                    row.add((null!=ordersResponse.getCostPrice() ? ordersResponse.getCostPrice(): BigDecimal.ZERO).add(null!=ordersResponse.getFreight() ? ordersResponse.getFreight(): BigDecimal.ZERO).toString());
                    row.add((null!=ordersResponse.getCostPrice() ? ordersResponse.getCostPrice(): BigDecimal.ZERO).toString());
                    row.add((null!=ordersResponse.getFreight() ? ordersResponse.getFreight(): BigDecimal.ZERO).toString());
                    row.add(ordersResponse.getSmallNote());
                    row.add(ordersResponse.getNote());
                    row.add(ordersResponse.getImportTimeText());
                    row.add(ExpressDicUtil.getMapKey(ordersResponse.getExpressCode()));
                    row.add(ordersResponse.getExpressNo());
                    row.add(ordersResponse.getUserName());
                    row.add(expressRecordStr);
                    row.add(ordersResponse.getUserTel());
                    row.add(ordersResponse.getProvince());
                    row.add(ordersResponse.getCity());
                    row.add(ordersResponse.getArea());
                    row.add(ordersResponse.getDeliveryAddress());
                    row.add(ordersResponse.getAuthenticatedName());
                    row.add(ordersResponse.getAuthenticatedCard());
                    row.add(ordersResponse.getReturnGoodStatusName());
                    row.add(ordersResponse.getServiceNo());
                    //客服电话
                    row.add("");
//                    if (!StringUtils.isEmpty(ordersResponse.getShopId()) && ordersResponse.getShopId().indexOf("GUOB") >= 0) {
//                        row.add(companyTel_GB);
//                    }else if (!StringUtils.isEmpty(ordersResponse.getShopId()) && ordersResponse.getShopId().indexOf("QMYX") >= 0){
//                        row.add(companyTel_QM);
//                    }else {
//                        row.add("");
//                    }
                    row.add(ordersResponse.getReceiveTimeText());
                    //订单来源
//                    row.add("");
                    data.add(row);
                } catch (Exception e) {
                    log.error("==={}", e);
                }finally {
                    countDownLatch.countDown();

                }
        });
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            log.error("===导出订单异常==={}", e);
        }
        log.info("=========================5=========================");
        productSpecIds = null;
        productSpecVOS = null;

        List<List<String>> head = getExcelHeadNew();
        // 生产excel
        OutputStream out;
        ExcelWriter excelWriter;
        String fileUrl = "";
        String fileName = "";
        try {
            Date date = new Date();
            SimpleDateFormat sbf = new SimpleDateFormat("yyyyMMddHHmmss");
            String nowDate = sbf.format(date);
            fileName = "BID" + exportOrdersRequest.getBankerId() + "-" + nowDate + ".xlsx";
            fileUrl = orderServicePath + fileName;
            out = new FileOutputStream(path + fileName);
            excelWriter = new ExcelWriter(out, ExcelTypeEnum.XLSX, true);
            Table table = new Table(0);
            table.setHead(head);
            Sheet sheet = new Sheet(0);
            sheet.setSheetName("订单列表");
            excelWriter.write0(data, sheet, table);
            excelWriter.finish();
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 插入导出记录
        YxBankerExportRecord yxBankerExportRecord = new YxBankerExportRecord();
        yxBankerExportRecord.setBankerId(exportOrdersRequest.getBankerId());
        yxBankerExportRecord.setFileName(fileName);
        yxBankerExportRecord.setFileUrl(fileUrl);
        yxBankerExportRecord.setCreateTime(new Date());
        yxBankerExportRecord.setExportType(1);
        bankerExportRecordMapper.insert(yxBankerExportRecord);
        // 返回成功
        return fileUrl;
    }

    public CommonPage getBankerOrderList(OrderRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<YxBankerOrder> bankerOrders = null;
        if (request.getLevel() != 0) { //0 供应链平台
            Optional.ofNullable(request.getBankerId())
                    .orElseThrow(() -> new ApiException("参数异常"));
            bankerOrders = bankerOrderMapper.getBankerOrders(request);
        } else {
            request.setBankerId(null);
            bankerOrders = bankerOrderMapper.getBankerOrders(request);
        }
        if (bankerOrders.size() <= 0) {
            return CommonPage.restPage(bankerOrders);
        }

        CommonPage page = CommonPage.restPage(bankerOrders);
        List<String> childOrderNoList = bankerOrders.stream().map(YxBankerOrder::getChildOrderNo).collect(Collectors.toList());
        List<YxExpressRecords> records = expressRecordsMapper.queryByChildOrderNoList(childOrderNoList);
        page.setList(bankerOrders
                .stream()
                .distinct()
                .map(item -> {
                    if (request.getLevel() != 0) {
                        item.setProductPrice(null);
                    }
                    String expressName = "";
                    if (!com.alibaba.excel.util.StringUtils.isEmpty(item.getExpressCode())) {
                        List<YxExpressDic> expressDicByExpressCode = expressDicService.queryExpressDicListByExpressValue(item.getExpressCode());
                        if (!CollectionUtils.isEmpty(expressDicByExpressCode)) {
                            expressName = expressDicByExpressCode.get(0).getExpressKey();
                        }
                    }
                    String typeno = getTypeno(String.valueOf(item.getId()));
                    String bankerName = getBankerName(item.getBankerId());

                    BankerOrderVO bankerOrderVO = new BankerOrderVO();
                    BeanUtils.copyProperties(item, bankerOrderVO);
                    OrdersResponse ordersResponse = new OrdersResponse(bankerOrderVO, expressName);
                    ordersResponse.setTypeno(typeno);
                    ordersResponse.setBankerName(bankerName);
                    ordersResponse.setOrderInfoStatus(item.getOrderInfoStatus());
                    ordersResponse.setDeliveryRemark(item.getDeliveryRemark());
                    String expressRecordStr = CollectionUtils.isEmpty(records)? "" :
                    records.stream().filter(record -> record.getChildOrderNo().equals(item.getChildOrderNo()))
                            .map(record -> ExpressDicUtil.getMapKey(record.getCompanyNo()) +":"+ record.getExpressEno()).collect(Collectors.joining("/"));
                    ordersResponse.setExpressRecordStr(expressRecordStr);
                    List<YxExpressRecords> collect = records.stream().filter(record -> record.getChildOrderNo().equals(item.getChildOrderNo())).collect(Collectors.toList());
                    List<ExpressRecordsRequest> expressRecordsRequests = CollectionUtils.isEmpty(collect) ? null : com.ytjj.qmyx.supplychain.common.utils.BeanUtils.convert(collect, ExpressRecordsRequest.class);
                    ordersResponse.setRecords(expressRecordsRequests);
                    return ordersResponse;
                })
                .collect(Collectors.toList()));
        return page;
    }

    public  void addDeliveryRemark(DeliverRemarkAddRequest request) {
        YxBankerOrder yxBankerOrder = bankerOrderMapper.selectByPrimaryKey(request.getBankerOrderId());
        if (null != yxBankerOrder) {
            yxBankerOrder.setDeliveryRemark(request.getDeliveryRemark());
            bankerOrderMapper.updateByPrimaryKey(yxBankerOrder);
        }
    }

    /**
     * 供应链订单列表
     *
     * @param request
     * @return
     */
    public CommonPage getSupplyChainOrderList(SupplyChainOrderListRequest request) {
        if(!StringUtils.isEmpty(request.getChildOrderNo())){
            String[] split = request.getChildOrderNo().split(",");
            if(split.length > 1){
                request.setChildOrderNos(Arrays.asList(split));
                request.setChildOrderNo(null);
            }
        }
        if (StringUtils.isNotBlank(request.getBankerName())){
            List<Integer> yxBankerIds = bankerMapper.selectBankerIdByName(request.getBankerName());
            if (CollectionUtils.isEmpty(yxBankerIds)){
                return CommonPage.restPage(new ArrayList<>());
            }
            request.setBankerIds(yxBankerIds);
        }

        if (!StringUtils.isEmpty(request.getIds())) {
            List<String> idStrList = Arrays.asList(request.getIds().split(","));
            if (!CollectionUtils.isEmpty(idStrList)) {
                request.setIdList(idStrList.stream().map(Integer::parseInt).collect(Collectors.toList()));
            }
        }
//        LocalDateTime ldt = LocalDateTime.now(ZoneId.systemDefault());
//        ldt = ldt.plusMonths(-3);
//        Date threeMonthBeforeDate = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
//        if (threeMonthBeforeDate.getTime() > request.getStartTime().getTime()) {
//            request.setStartTime(threeMonthBeforeDate);
//        }

        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<SupplyChainOrderListResponse> list = ordersMapper.querySupplyChainOrderInfo(request);
        if (CollectionUtils.isEmpty(list)){
                return CommonPage.restPage(new ArrayList<>());
            }

        List<String> childOrderNoList = list.stream().map(SupplyChainOrderListResponse::getChildOrderNo).collect(Collectors.toList());
        List<YxExpressRecords> records = expressRecordsMapper.queryByChildOrderNoList(childOrderNoList);

        //支付信息
        Example ordersPayExample = new Example(YxOrdersPay.class);
        ordersPayExample.createCriteria().andIn("childOrderNo", childOrderNoList);
        List<YxOrdersPay> yxOrdersPayList = ordersPayMapper.selectByExample(ordersPayExample);


        //订单异常备注
        List<OrderExceptionNoteResponse> orderExceptionNotes = orderExceptionService.selectNoteByChildrenOrderNo(childOrderNoList);

        List<Integer> bankerIds = list.stream().filter(item -> null != item.getBankerId()).map(SupplyChainOrderListResponse::getBankerId).collect(Collectors.toList());
        //供应商名称
        List<BankerResponse> bankerResponses = productMapper.selectBankerMsgByBankerId(bankerIds);
        //供应链商品id
        List<Integer> productIds = list.stream().distinct().map(SupplyChainOrderListResponse::getProductId).collect(Collectors.toList());
        //根据商品id查信息
        List<YxProduct> productList = productMapper.selectByProductIds(productIds);
        //最新物流
        Set<String> expressNo = list.stream().map(e -> e.getExpressNo()).collect(Collectors.toSet());
        Example example = new Example(YxExpressOrders.class);
        example.createCriteria().andIn("expressEno", expressNo).andEqualTo("type",1).andEqualTo("invalidFlag",0);
        example.orderBy("id").desc();
        List<YxExpressOrders> expressOrders = expressOrderService.selectByExample(example);
        Map<String, List<YxExpressOrders>> expressMap = expressOrders.stream().collect(Collectors.groupingBy(e -> e.getExpressEno()));

//        //规格供货价
//        Set<Integer> productSpecIds = list.stream().filter(item -> null != item.getProductSpecId()).map(SupplyChainOrderListResponse::getProductSpecId).collect(Collectors.toSet());
//        Example example = new Example(YxProductSpec.class);
//        example.createCriteria().andIn("id", productSpecIds);
//        List<YxProductSpec> yxProductSpecs = productSpecMapper.selectByExample(example);

        //商品分类
        List<YxProductCategory> yxProductCategoryList = new ArrayList<>();
        //售后信息
        List<YxReturnGoods> yxReturnGoodsList = new ArrayList<>();

        List<YxShopInfo> shopInfoResponses = new ArrayList<>();

        //是否需要修改订单的导出状态
        boolean flag = false;
        if (request.getPageSize() > 10) {
            //订单来源
            shopInfoResponses = productMapper.selectShopINfoByShopIds();

            flag = true;
            //一级分类
            Set<Integer> topCategoryIds = productList.stream().filter(item -> null != item.getTopCategoryId()).map(YxProduct::getTopCategoryId).collect(Collectors.toSet());
            //二级分类
            Set<Integer> categoryIds = productList.stream().filter(item -> null != item.getCategoryId()).map(YxProduct::getCategoryId).collect(Collectors.toSet());
            //三级分类
            Set<Integer> bottomCategoryIds = productList.stream().filter(item -> null != item.getBottomCategoryId()).map(YxProduct::getBottomCategoryId).collect(Collectors.toSet());
            topCategoryIds.addAll(categoryIds);
            topCategoryIds.addAll(bottomCategoryIds);
            List<Integer> ids = new ArrayList<>(topCategoryIds);
            if (!CollectionUtils.isEmpty(ids)) {
                if (ids.size() >= 20) {
                    int num = ids.size() / 20;
                    int more = ids.size() % 20;
                    if (more > 0) {
                        num = num + 1;
                    }
                    for (int i = 0; i < num - 1; i++) {
                        yxProductCategoryList.addAll(productMapper.selectCategoryById(ids.subList(i * 20, i * 20 + 20)));
                    }
                    yxProductCategoryList.addAll(productMapper.selectCategoryById(ids.subList((num - 1) * 20, ids.size())));
                } else {
                    yxProductCategoryList = productMapper.selectCategoryById(ids);
                }
            }

            //售后数据
//            List<Integer> orderInfoIds = list.stream().filter(item -> null != item.getOrderInfoId()).map(SupplyChainOrderListResponse::getOrderInfoId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(childOrderNoList)) {
                if (childOrderNoList.size() >= 20) {
                    int num = childOrderNoList.size() / 20;
                    int more = childOrderNoList.size() % 20;
                    if (more > 0) {
                        num = num + 1;
                    }
                    for (int i = 0; i < num - 1; i++) {
                        yxReturnGoodsList.addAll(returnGoodsMapper.selectDateByChildOrderNos(childOrderNoList.subList(i * 20, i * 20 + 20)));
                    }
                    yxReturnGoodsList.addAll(returnGoodsMapper.selectDateByChildOrderNos(childOrderNoList.subList((num - 1) * 20, childOrderNoList.size())));
                } else {
                    yxReturnGoodsList = returnGoodsMapper.selectDateByChildOrderNos(childOrderNoList);
                }
            }
        }
        List<YxProductCategory> finalYxProductCategoryList = yxProductCategoryList;
        List<YxReturnGoods> finalYxReturnGoodsList = yxReturnGoodsList;
        List<YxShopInfo> finalShopInfoResponses = shopInfoResponses;
        //遍历
        list.stream().forEach(item -> {

            if(request.getIsLimitRole()) {
                if (!CollectionUtils.isEmpty(yxOrdersPayList)) {
                    List<YxOrdersPay> collect = yxOrdersPayList.stream().filter(item2 -> item.getChildOrderNo().equals(item2.getChildOrderNo())).collect(Collectors.toList());
                    item.setRealTotalMoney(CollectionUtils.isEmpty(collect) ? null :  collect.get(0).getAmount());
                }
            }

            List<YxProduct> products = productList.stream().filter(product -> item.getProductId().equals(product.getId())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(products)){
                YxProduct yxProduct = products.get(0);
                item.setTypeno(yxProduct.getTypeno());
                item.setTopCategoryId(yxProduct.getTopCategoryId());
                item.setCategoryId(yxProduct.getCategoryId());
                item.setBottomCategoryId(yxProduct.getBottomCategoryId());
            }

            item.setSupplyPrice(item.getProductPrice());
            //订单来源
            if (!CollectionUtils.isEmpty(finalShopInfoResponses)) {
                List<YxShopInfo> collect = finalShopInfoResponses.stream().filter(yxShopInfo -> yxShopInfo.getShopId().equals(item.getShopId())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(collect)) {
                    item.setShopName(collect.get(0).getName());
                }
            }
            //商品分类
            if (!CollectionUtils.isEmpty(finalYxProductCategoryList)) {
                List<YxProductCategory> collect = finalYxProductCategoryList.stream().filter(yxProductCategory -> yxProductCategory.getId().equals(item.getTopCategoryId())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(collect)) {
                    item.setTopCategoryTitle(collect.get(0).getTitle());
                }
                List<YxProductCategory> collect1 = finalYxProductCategoryList.stream().filter(yxProductCategory -> yxProductCategory.getId().equals(item.getCategoryId())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(collect1)) {
                    item.setCategoryTitle(collect1.get(0).getTitle());
                }
                List<YxProductCategory> collect2 = finalYxProductCategoryList.stream().filter(yxProductCategory -> yxProductCategory.getId().equals(item.getBottomCategoryId())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(collect2)) {
                    item.setBottomCategoryTitle(collect2.get(0).getTitle());
                }
            }
            //售后数据
            if (!CollectionUtils.isEmpty(finalYxReturnGoodsList)) {
                List<YxReturnGoods> collect = finalYxReturnGoodsList.stream().filter(yxReturnGoods -> yxReturnGoods.getOrdersInfoId().equals(item.getOrderInfoId())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(collect)) {
                    item.setServiceNo(collect.get(0).getServiceNo());
                    item.setAmount(collect.get(0).getAmount());
                    item.setReturnGoodStatus(collect.get(0).getStatus().toString());
                }
            }

            //供应商名称
            if (!CollectionUtils.isEmpty(bankerResponses) && null != item.getBankerId()) {
                List<BankerResponse> collect = bankerResponses.stream().filter(bankerResponse -> null != bankerResponse.getBankerId() && bankerResponse.getBankerId().equals(item.getBankerId())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(collect)) {
                    BankerResponse bankerResponse = collect.get(0);
                    item.setBankerName(bankerResponse.getBankerName());
                    item.setBuyer(bankerResponse.getBuyer());
                }
            }

            if (!com.alibaba.excel.util.CollectionUtils.isEmpty(orderExceptionNotes)) {
                List<OrderExceptionNoteResponse> notes = orderExceptionNotes.stream().filter(item2 -> item.getChildOrderNo().equals(item2.getChildOrderNo())).collect(Collectors.toList());
                if (!com.alibaba.excel.util.CollectionUtils.isEmpty(notes)) {
                    item.setOrderExceptionNoteStr(notes.get(0).getAdminName()+ " " + notes.get(0).getContent() +
                            " 时间为"  + DateUtil.dateToStr(notes.get(0).getCreateTime()));
                }

            }

            //赋值物流最新状态
            String itemExpressNo = item.getExpressNo();
            String itemExpressCode = item.getExpressCode();
            if (StringUtils.isNotEmpty(itemExpressNo) && StringUtils.isNotEmpty(itemExpressCode)) {
                try {
                    List<YxExpressOrders> expressOrdersList = expressMap.get(itemExpressNo);
                    if (!CollectionUtils.isEmpty(expressOrdersList)) {
                        List<YxExpressOrders> curExpressList = expressOrdersList.stream().filter(e -> e.getCompanyNo().equals(itemExpressCode)).collect(Collectors.toList());
                        YxExpressOrders curExpress = curExpressList.stream().max(Comparator.comparingInt(YxExpressOrders::getId)).get();
                        if (null != curExpress) {
                            List<QueryTrackData> queryTrackDatas = JSON.parseArray(curExpress.getInfoText(), QueryTrackData.class);
                            if(!CollectionUtils.isEmpty(queryTrackDatas)){
                                QueryTrackData queryTrackData = queryTrackDatas.get(0);
                                item.setLatestExpressState(queryTrackData.getFtime()+" "+ExpressEnums.getStatusName(curExpress.getStatus().toString()));
                            }
                        }
                    }
                } catch (Exception e) {
                    log.info("订单列表物流轨迹转换出错！{}", e);
                }
            }

//            //供货价
//            if (!CollectionUtils.isEmpty(yxProductSpecs)) {
//                List<YxProductSpec> collect = yxProductSpecs.stream().filter(productSpec -> productSpec.getId().equals(item.getProductSpecId())).collect(Collectors.toList());
//                if (!CollectionUtils.isEmpty(collect)) {
//                    item.setSupplyPrice(collect.get(0).getSupplyPrice());
//                    item.setCostPrice(collect.get(0).getCostPrice());
//                }
//            }
            String expressRecordStr = CollectionUtils.isEmpty(records)? "" :
                    records.stream().filter(record -> record.getChildOrderNo().equals(item.getChildOrderNo()))
                            .map(record -> ExpressDicUtil.getMapKey(record.getCompanyNo()) +":"+ record.getExpressEno()).collect(Collectors.joining("/"));
            item.setExpressRecordStr(expressRecordStr);
            List<YxExpressRecords> collect = records.stream().filter(record -> record.getChildOrderNo().equals(item.getChildOrderNo())).collect(Collectors.toList());
            List<ExpressRecordsRequest> expressRecordsRequests = CollectionUtils.isEmpty(collect) ? null : com.ytjj.qmyx.supplychain.common.utils.BeanUtils.convert(collect, ExpressRecordsRequest.class);
            item.setRecords(expressRecordsRequests);

            //处理地址显示问题
            if (StringUtils.isNotBlank(item.getDeliveryAddress()) && !item.getDeliveryAddress().contains("省")) {
                item.setDeliveryAddress(item.getProvince() + item.getCity() + item.getArea() + item.getDeliveryAddress());
            }
        });
        if (request.getPageSize() > 10) {
//            List<SupplyChainOrderListResponse> collect = list.stream().sorted(Comparator.comparing(SupplyChainOrderListResponse::getId).reversed()).collect(Collectors.toList());
            return CommonPage.restPage(list);
        }
        //如果为true,需要更新导出状态
//        if (flag){
//            List<String> collect = list.stream().filter(item -> null != item.getIsExport() && item.getIsExport() == 0).map(SupplyChainOrderListResponse::getChildOrderNo).collect(Collectors.toList());
//            bankerOrderMapper.updateIsExportByChildOrderNoList(collect);
//        }

        return CommonPage.restPage(list);
    }

    /**
     * 导出供应链订单列表
     * @param request
     * @return
     */
    public String exportBankerOrderList(SupplyChainOrderListRequest request)throws IOException{

        //查询要导出的数据，第一页查1000条
        Date date = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("yyyyMMddHHmmss");
        String nowDate = sbf.format(date);
        String fileName;
        String fileUrl;
        OutputStream outputStream =null;
        try {
            fileName =  nowDate + ".xlsx";
            outputStream =new FileOutputStream(path + fileName);;
            fileUrl =   orderServicePath + fileName;
            //记录总数:实际中需要根据查询条件进行统计即可:一共多少条
            if (StringUtils.isNotBlank(request.getBankerName())){
                List<Integer> yxBankerIds = bankerMapper.selectBankerIdByName(request.getBankerName());
                if (!CollectionUtils.isEmpty(yxBankerIds)){
                    request.setBankerIds(yxBankerIds);
                }
            }
            Integer totalCount = ordersMapper.queryExportOrderCount(request);
            if (totalCount <= 0) {
                throw new ApiException("查询数据为空，导出失败");
            }

            //每一个Sheet存放100w条数据
            Integer sheetDataRows = PER_SHEET_ROW_COUNT;
            //每次写入的数据量20w,每页查询20W
            Integer writeDataRows = PER_WRITE_ROW_COUNT;
            //计算需要的Sheet数量
            Integer sheetNum = totalCount % sheetDataRows == 0 ? (totalCount / sheetDataRows) : (totalCount / sheetDataRows + 1);
            //计算一般情况下每一个Sheet需要写入的次数(一般情况不包含最后一个sheet,因为最后一个sheet不确定会写入多少条数据)
            Integer oneSheetWriteCount = sheetDataRows / writeDataRows;
            //计算最后一个sheet需要写入的次数
            Integer lastSheetWriteCount = totalCount % sheetDataRows == 0 ? oneSheetWriteCount : (totalCount % sheetDataRows % writeDataRows == 0 ? (totalCount / sheetDataRows / writeDataRows) : (totalCount / sheetDataRows / writeDataRows + 1));
            if(totalCount >= writeDataRows && totalCount< sheetDataRows ) {
                lastSheetWriteCount = totalCount % writeDataRows == 0 ? totalCount/writeDataRows : totalCount/writeDataRows +1;
            }
            //必须放到循环外，否则会刷新流
            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
            //开始分批查询分次写入
            for (int i = 0; i < sheetNum; i++) {
                //创建Sheet
                WriteSheet sheet = new WriteSheet();
                sheet.setSheetName("Sheet"+i);
                sheet.setSheetNo(i);
                StopWatch stopWatch = new StopWatch("导出监听");
                //循环写入次数: j的自增条件是当不是最后一个Sheet的时候写入次数为正常的每个Sheet写入的次数,如果是最后一个就需要使用计算的次数lastSheetWriteCount
                for (int j = 0; j < (i != sheetNum - 1 ? oneSheetWriteCount : lastSheetWriteCount); j++) {
                    //分页查询一次20w
                    stopWatch.start("开始======"+j+"查询数据并且写入到excel");
                    Page page1 = new Page(j +1 + oneSheetWriteCount * i, writeDataRows);
                    //查询分页列表---按照自己的业务查列表，分页这个一定要使用这个：page1.getPageNum(),page1.getPageSize()！！！
                    request.setPageNum(page1.getPageNum());
                    request.setPageSize(page1.getPageSize());
                    log.info("查询导出参数:{}",JSONObject.toJSON(request));
                    List<SupplyChainExportOrdersReponse> data = getExportBankerOrderList(request);
                    log.info("查询导出返回条数:{}",data.size());
                    WriteSheet writeSheet = EasyExcel.writerSheet(i, "Sheet" + (i + 1)).head(SupplyChainExportOrdersReponse.class)
                            .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
                    excelWriter.write(data, writeSheet);
                    stopWatch.stop();
                }
                log.info("Sheet导出: " + stopWatch.prettyPrint());
            }
            // 插入导出记录
            YxBankerExportRecord yxBankerExportRecord = new YxBankerExportRecord();
            yxBankerExportRecord.setFileName(fileName);
            yxBankerExportRecord.setFileUrl(fileUrl);
            yxBankerExportRecord.setCreateTime(new Date());
            yxBankerExportRecord.setExportType(2);
            bankerExportRecordMapper.insert(yxBankerExportRecord);

            excelWriter.finish();
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            log.error("导出错误：{}",e.getMessage());
            throw e;
        }finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }

        return fileUrl;
    }

    public String newExportBankerOrderList(SupplyChainOrderListRequest request,HttpServletResponse response)throws IOException {

        //查询要导出的数据，第一页查1000条
        Date date = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("yyyyMMddHHmmss");
        String nowDate = sbf.format(date);
        String fileName;
        String fileUrl;
        OutputStream outputStream =null;
        try {
            fileName =  nowDate + ".xlsx";
            outputStream =new FileOutputStream(path + fileName);
            fileUrl =   orderServicePath + fileName;
            //记录总数:实际中需要根据查询条件进行统计即可:一共多少条
            if (StringUtils.isNotBlank(request.getBankerName())){
                List<Integer> yxBankerIds = bankerMapper.selectBankerIdByName(request.getBankerName());
                if (!CollectionUtils.isEmpty(yxBankerIds)){
                    request.setBankerIds(yxBankerIds);
                }
            }
            if(!StringUtils.isEmpty(request.getChildOrderNo())){
                String[] split = request.getChildOrderNo().split(",");
                if(split.length > 1){
                    request.setChildOrderNos(Arrays.asList(split));
                    request.setChildOrderNo(null);
                }
            }
            Integer totalCount = ordersMapper.queryExportOrderCount(request);
            if (totalCount <= 0) {
                throw new ApiException("查询数据为空，导出失败");
            }

            //每一个Sheet存放100w条数据
            Integer sheetDataRows = PER_SHEET_ROW_COUNT;
            //每次写入的数据量20w,每页查询20W
            Integer writeDataRows = PER_WRITE_ROW_COUNT;
            //计算需要的Sheet数量
            Integer sheetNum = totalCount % sheetDataRows == 0 ? (totalCount / sheetDataRows) : (totalCount / sheetDataRows + 1);
            //计算一般情况下每一个Sheet需要写入的次数(一般情况不包含最后一个sheet,因为最后一个sheet不确定会写入多少条数据)
            Integer oneSheetWriteCount = sheetDataRows / writeDataRows;
            //计算最后一个sheet需要写入的次数
            Integer lastSheetWriteCount = totalCount % sheetDataRows == 0 ? oneSheetWriteCount : (totalCount % sheetDataRows % writeDataRows == 0 ? (totalCount / sheetDataRows / writeDataRows) : (totalCount / sheetDataRows / writeDataRows + 1));
            if(totalCount >= writeDataRows && totalCount< sheetDataRows ) {
                lastSheetWriteCount = totalCount % writeDataRows == 0 ? totalCount/writeDataRows : totalCount/writeDataRows +1;
            }
            //必须放到循环外，否则会刷新流
            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();

            CountDownLatch countDownLatch = new CountDownLatch(Math.toIntExact(sheetNum));

            //开始分批查询分次写入 sheetNum
            for (int i = 0; i < sheetNum; i++) {
                //创建Sheet
                WriteSheet sheet = new WriteSheet();
                sheet.setSheetName("Sheet"+i);
                sheet.setSheetNo(i);
                int finalNum = i;
                Integer finalLastSheetWriteCount = lastSheetWriteCount;

                int finalI = i;
                threadPoolTaskExecutor.submit(()->{
                    //循环写入次数, j的自增条件是当不是最后一个Sheet的时候写入次数为正常的每个Sheet写入的次数,如果是最后一个就需要使用计算的次数lastSheetWriteCount
                    for (int j = 0; j < (finalNum != sheetNum - 1 ? oneSheetWriteCount : finalLastSheetWriteCount); j++) {
                        Page page1 = new Page(j +1 + oneSheetWriteCount * finalI, writeDataRows);
                        //查询分页列表---按照自己的业务查列表，分页这个一定要使用这个：page1.getPageNum(),page1.getPageSize()！！！
                        request.setPageNum(page1.getPageNum());
                        request.setPageSize(page1.getPageSize());
                        log.info("查询导出参数:{}",JSONObject.toJSON(request));
                        List<SupplyChainExportOrdersReponse> data = getExportBankerOrderList(request);
                        log.info("查询导出返回条数:{}",data.size());
                        WriteSheet writeSheet = EasyExcel.writerSheet(finalI, "Sheet" + (finalI + 1)).head(SupplyChainExportOrdersReponse.class)
                                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
                        excelWriter.write(data, writeSheet);
                    }

                    countDownLatch.countDown();
                });
            }

            try{
                countDownLatch.await();
            }catch (Exception e){
                e.printStackTrace();
            }

            // 插入导出记录
            YxBankerExportRecord yxBankerExportRecord = new YxBankerExportRecord();
            yxBankerExportRecord.setFileName(fileName);
            yxBankerExportRecord.setFileUrl(fileUrl);
            yxBankerExportRecord.setCreateTime(new Date());
            yxBankerExportRecord.setExportType(2);
            bankerExportRecordMapper.insert(yxBankerExportRecord);

            excelWriter.finish();
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            log.error("导出错误：{}",e.getMessage());
            throw e;
        }finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }

        return fileUrl;
    }


    public String exportOrderInfoList(List<OrdersInfoExportResponse> responses)throws IOException{
        Date date = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("yyyyMMddHHmmss");
        String nowDate = sbf.format(date);
        String fileName = null;
        String fileUrl = null;
        OutputStream outputStream =null;
        if (!CollectionUtils.isEmpty(responses)) {
            try{
                fileName =  "子订单-"+nowDate + ".xlsx";
                outputStream =new FileOutputStream(path + fileName);;
                fileUrl =    fileName;
                ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
                WriteSheet writeSheet = EasyExcel.writerSheet(fileName).head(OrdersInfoExportResponse.class)
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
                excelWriter.write(responses, writeSheet);

                excelWriter.finish();
                outputStream.flush();
                outputStream.close();

            }catch (Exception e) {
                log.error("导出错误：{}",e.getMessage());
            }finally {
                if (outputStream != null) {
                    outputStream.close();
                }
            }
        }

        // 插入导出记录
        YxBankerExportRecord yxBankerExportRecord = new YxBankerExportRecord();
        yxBankerExportRecord.setFileName(fileName);
        yxBankerExportRecord.setFileUrl(fileUrl);
        yxBankerExportRecord.setCreateTime(new Date());
        yxBankerExportRecord.setExportType(3);
        bankerExportRecordMapper.insert(yxBankerExportRecord);
        return  fileUrl;
    }


    public String exportBankerOrderListV2(SupplyChainOrderListRequest request,HttpServletResponse response)throws IOException {

        //查询要导出的数据，第一页查1000条
        Date date = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("yyyyMMddHHmmss");
        String nowDate = sbf.format(date);
        String fileName;
        String fileUrl;
        OutputStream outputStream =null;
        try {
            fileName =  nowDate + ".xlsx";
            outputStream =new FileOutputStream(path + fileName);
            fileUrl =   orderServicePath + fileName;
            //记录总数:实际中需要根据查询条件进行统计即可:一共多少条
            if (StringUtils.isNotBlank(request.getBankerName())){
                List<Integer> yxBankerIds = bankerMapper.selectBankerIdByName(request.getBankerName());
                if (!CollectionUtils.isEmpty(yxBankerIds)){
                    request.setBankerIds(yxBankerIds);
                }
            }
            if(!StringUtils.isEmpty(request.getChildOrderNo())){
                String[] split = request.getChildOrderNo().split(",");
                if(split.length > 1){
                    request.setChildOrderNos(Arrays.asList(split));
                    request.setChildOrderNo(null);
                }
            }
            Integer totalCount = ordersMapper.queryExportOrderCount(request);
            if (totalCount <= 0) {
                throw new ApiException("查询数据为空，导出失败");
            }

            //每一个Sheet存放100w条数据
            Integer sheetDataRows = PER_SHEET_ROW_COUNT;
            //每次写入的数据量20w,每页查询20W
            Integer writeDataRows = PER_WRITE_ROW_COUNT;
            //计算需要的Sheet数量
            Integer sheetNum = totalCount % sheetDataRows == 0 ? (totalCount / sheetDataRows) : (totalCount / sheetDataRows + 1);
            //计算一般情况下每一个Sheet需要写入的次数(一般情况不包含最后一个sheet,因为最后一个sheet不确定会写入多少条数据)
            Integer oneSheetWriteCount = sheetDataRows / writeDataRows;
            //计算最后一个sheet需要写入的次数
            Integer lastSheetWriteCount = totalCount % sheetDataRows == 0 ? oneSheetWriteCount : (totalCount % sheetDataRows % writeDataRows == 0 ? (totalCount / sheetDataRows / writeDataRows) : (totalCount / sheetDataRows / writeDataRows + 1));
            if(totalCount >= writeDataRows && totalCount< sheetDataRows ) {
                lastSheetWriteCount = totalCount % writeDataRows == 0 ? totalCount/writeDataRows : totalCount/writeDataRows +1;
            }
            //必须放到循环外，否则会刷新流
            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
            List<CompletableFuture> completableFutures = new ArrayList<>();

            //开始分批查询分次写入 sheetNum
            for (int i = 0; i < sheetNum; i++) {
                //创建Sheet
                WriteSheet sheet = new WriteSheet();
                sheet.setSheetName("Sheet"+i);
                sheet.setSheetNo(i);
                int finalNum = i;
                Integer finalLastSheetWriteCount = lastSheetWriteCount;

                int finalI = i;
                //循环写入次数, j的自增条件是当不是最后一个Sheet的时候写入次数为正常的每个Sheet写入的次数,如果是最后一个就需要使用计算的次数lastSheetWriteCount
                for (int j = 0; j < (finalNum != sheetNum - 1 ? oneSheetWriteCount : finalLastSheetWriteCount); j++) {
                    int finalJ = j;
                    CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() ->{
                        Page page1 = new Page(finalJ +1 + oneSheetWriteCount * finalI, writeDataRows);
                        //查询分页列表---按照自己的业务查列表，分页这个一定要使用这个：page1.getPageNum(),page1.getPageSize()！！！
                        request.setPageNum(page1.getPageNum());
                        request.setPageSize(page1.getPageSize());
                        log.info("查询导出参数:{}",JSONObject.toJSON(request));
                        List<SupplyChainExportOrdersReponse> data = getExportBankerOrderList(request);
                        log.info("查询导出返回条数:{}",data.size());
                        if (!CollectionUtils.isEmpty(data)) {
                            WriteSheet writeSheet = EasyExcel.writerSheet(finalI, "Sheet" + (finalI + 1)).head(SupplyChainExportOrdersReponse.class)
                                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
                            synchronized (excelWriter) {
                                excelWriter.write(data, writeSheet);
                            }
                        }
                    },threadPoolTaskExecutor);
                    completableFutures.add(completableFuture);
                }
            }
            for (CompletableFuture completableFuture : completableFutures) {
                completableFuture.join();
            }

            // 插入导出记录
            YxBankerExportRecord yxBankerExportRecord = new YxBankerExportRecord();
            yxBankerExportRecord.setFileName(fileName);
            yxBankerExportRecord.setFileUrl(fileUrl);
            yxBankerExportRecord.setCreateTime(new Date());
            yxBankerExportRecord.setExportType(2);
            bankerExportRecordMapper.insert(yxBankerExportRecord);

            excelWriter.finish();
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            log.error("导出错误：{}",e.getMessage());
            throw e;
        }finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }

        return fileUrl;
    }


    public List<SupplyChainExportOrdersReponse> getExportBankerOrderList(SupplyChainOrderListRequest request) {

        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<SupplyChainImportOrdersResponse> responses = ordersMapper.queryExportOrderList(request);
        List<SupplyChainExportOrdersReponse> data = new ArrayList<>();
        if (!CollectionUtils.isEmpty(responses)) {
            List<String> childOrderNoList = responses.stream().map(SupplyChainImportOrdersResponse::getChildOrderNo).collect(Collectors.toList());
//            List<YxExpressRecords> records = expressRecordsMapper.queryByChildOrderNoList(childOrderNoList);

            List<Integer> bankerIds = responses.stream().filter(item -> null != item.getBankerId()).map(SupplyChainImportOrdersResponse::getBankerId).collect(Collectors.toList());
            //供应商名称
            List<BankerResponse> bankerResponses = productMapper.selectBankerMsgByBankerId(bankerIds);
            //供应链商品id
            List<Integer> productIds = responses.stream().distinct().map(SupplyChainImportOrdersResponse::getProductId).collect(Collectors.toList());
//            //根据商品id查信息
            List<YxProduct> productList = productMapper.selectByProductIds(productIds);
            //最新物流
            Map<String, List<YxExpressOrders>> expressMap;
            if (request.getStatus()!=null && request.getStatus().equals(2)){
                Set<String> expressNo = responses.stream().map(e -> e.getExpressNo()).filter(x->StringUtils.isNotBlank(x)).collect(Collectors.toSet());
                Example example = new Example(YxExpressOrders.class);
                example.createCriteria().andIn("expressEno", expressNo).andEqualTo("type",1).andEqualTo("invalidFlag",0);
                example.orderBy("id").desc();
                List<YxExpressOrders> expressOrders = expressOrderService.selectByExample(example);
                expressMap = expressOrders.stream().collect(Collectors.groupingBy(e -> e.getExpressEno()));
            } else {
                expressMap = null;
            }
//        //规格供货价
//        Set<Integer> productSpecIds = list.stream().filter(item -> null != item.getProductSpecId()).map(SupplyChainOrderListResponse::getProductSpecId).collect(Collectors.toSet());
//        Example example = new Example(YxProductSpec.class);
//        example.createCriteria().andIn("id", productSpecIds);
//        List<YxProductSpec> yxProductSpecs = productSpecMapper.selectByExample(example);

            //订单异常备注
            List<OrderExceptionNoteResponse> orderExceptionNotes = orderExceptionService.selectNoteByChildrenOrderNo(childOrderNoList);

            //支付信息
            Example ordersPayExample = new Example(YxOrdersPay.class);
            ordersPayExample.createCriteria().andIn("childOrderNo", childOrderNoList);
            List<YxOrdersPay> yxOrdersPayList = ordersPayMapper.selectByExample(ordersPayExample);

            //商品分类
            List<YxProductCategory> yxProductCategoryList = new ArrayList<>();
            //售后信息
            List<YxReturnGoods> yxReturnGoodsList = new ArrayList<>();

            List<YxShopInfo> shopInfoResponses = new ArrayList<>();

            //是否需要修改订单的导出状态
            boolean flag = false;
            if (request.getPageSize() > 10) {
                //订单来源
                shopInfoResponses = productMapper.selectShopINfoByShopIds();

                flag = true;
                //一级分类
                Set<Integer> topCategoryIds = productList.stream().filter(item -> null != item.getTopCategoryId()).map(YxProduct::getTopCategoryId).collect(Collectors.toSet());
                //二级分类
                Set<Integer> categoryIds = productList.stream().filter(item -> null != item.getCategoryId()).map(YxProduct::getCategoryId).collect(Collectors.toSet());
                //三级分类
                Set<Integer> bottomCategoryIds = productList.stream().filter(item -> null != item.getBottomCategoryId()).map(YxProduct::getBottomCategoryId).collect(Collectors.toSet());
                topCategoryIds.addAll(categoryIds);
                topCategoryIds.addAll(bottomCategoryIds);
                List<Integer> ids = new ArrayList<>(topCategoryIds);
                if (!CollectionUtils.isEmpty(ids)) {
                    if (ids.size() >= 20) {
                        int num = ids.size() / 20;
                        int more = ids.size() % 20;
                        if (more > 0) {
                            num = num + 1;
                        }
                        for (int i = 0; i < num - 1; i++) {
                            yxProductCategoryList.addAll(productMapper.selectCategoryById(ids.subList(i * 20, i * 20 + 20)));
                        }
                        yxProductCategoryList.addAll(productMapper.selectCategoryById(ids.subList((num - 1) * 20, ids.size())));
                    } else {
                        yxProductCategoryList = productMapper.selectCategoryById(ids);
                    }
                }

                //售后数据
//                List<Integer> orderInfoIds = responses.stream().filter(item -> null != item.getOrderInfoId()).map(SupplyChainImportOrdersResponse::getOrderInfoId).collect(Collectors.toList());
//                if (!CollectionUtils.isEmpty(childOrderNoList)) {
//                    if (childOrderNoList.size() >= 20) {
//                        int num = childOrderNoList.size() / 20;
//                        int more = childOrderNoList.size() % 20;
//                        if (more > 0) {
//                            num = num + 1;
//                        }
//                        for (int i = 0; i < num - 1; i++) {
//                            yxReturnGoodsList.addAll(returnGoodsMapper.selectDateByChildOrderNos(childOrderNoList.subList(i * 20, i * 20 + 20)));
//                        }
//                        yxReturnGoodsList.addAll(returnGoodsMapper.selectDateByChildOrderNos(childOrderNoList.subList((num - 1) * 20, childOrderNoList.size())));
//                    } else {
//                        yxReturnGoodsList = returnGoodsMapper.selectDateByChildOrderNos(childOrderNoList);
//                    }
//                }
            }

            List<YxProductCategory> finalYxProductCategoryList = yxProductCategoryList;
//            List<YxReturnGoods> finalYxReturnGoodsList = yxReturnGoodsList;
            List<YxShopInfo> finalShopInfoResponses = shopInfoResponses;
            //遍历

            responses.stream().forEach(item -> {
                SupplyChainExportOrdersReponse re = new SupplyChainExportOrdersReponse();
                BeanUtils.copyProperties(item,re);
                re.setProductId(item.getProductId().toString());
                if(request.getIsLimitRole()) {
                    if (!CollectionUtils.isEmpty(yxOrdersPayList)) {
                        List<YxOrdersPay> collect = yxOrdersPayList.stream().filter(item2 -> re.getChildOrderNo().equals(item2.getChildOrderNo())).collect(Collectors.toList());
                        re.setRealTotalMoney(CollectionUtils.isEmpty(collect) ? null :  collect.get(0).getAmount());
                    }
                }
                List<YxProduct> products = productList.stream().filter(product -> item.getProductId().equals(product.getId())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(products)){
                    YxProduct yxProduct = products.get(0);
//                    re.setTypeno(yxProduct.getTypeno());
                    item.setTopCategoryId(yxProduct.getTopCategoryId());
                    item.setCategoryId(yxProduct.getCategoryId());
                    item.setBottomCategoryId(yxProduct.getBottomCategoryId());
                }
                re.setSupplyPrice(item.getProductPrice()==null ? "" :item.getProductPrice().toString());
                //订单来源
                if (!CollectionUtils.isEmpty(finalShopInfoResponses)) {
                    List<YxShopInfo> collect = finalShopInfoResponses.stream().filter(yxShopInfo -> yxShopInfo.getShopId().equals(item.getShopId())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(collect)) {
                        re.setOrderSource(collect.get(0).getName()!=null?collect.get(0).getName().substring(0,2):"");
                    }
                }
                //商品分类
                if (!CollectionUtils.isEmpty(finalYxProductCategoryList)) {
                    List<YxProductCategory> collect = finalYxProductCategoryList.stream().filter(yxProductCategory -> yxProductCategory.getId().equals(item.getTopCategoryId())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(collect)) {
                        re.setTopCategoryTitle(collect.get(0).getTitle());
                    }
                    List<YxProductCategory> collect1 = finalYxProductCategoryList.stream().filter(yxProductCategory -> yxProductCategory.getId().equals(item.getCategoryId())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(collect1)) {
                        re.setCategoryTitle(collect1.get(0).getTitle());
                    }
                    List<YxProductCategory> collect2 = finalYxProductCategoryList.stream().filter(yxProductCategory -> yxProductCategory.getId().equals(item.getBottomCategoryId())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(collect2)) {
                        re.setBottomCategoryTitle(collect2.get(0).getTitle());
                    }
                }
                //售后数据
//                if (!CollectionUtils.isEmpty(finalYxReturnGoodsList)) {
//                    List<YxReturnGoods> collect = finalYxReturnGoodsList.stream().filter(yxReturnGoods -> yxReturnGoods.getOrdersInfoId().equals(item.getOrderInfoId())).collect(Collectors.toList());
//                    if (!CollectionUtils.isEmpty(collect)) {
//                        re.setServiceNo(collect.get(0).getServiceNo());
//                        re.setReturnGoodStatus(collect.get(0).getStatus() == null ? "" : ReturnGoodsStatusEnums.getStatusDesc(String.valueOf(collect.get(0).getStatus())));
//
//                    }
//                }

                //供应商名称
                if (!CollectionUtils.isEmpty(bankerResponses) && null != item.getBankerId()) {
                    List<BankerResponse> collect = bankerResponses.stream().filter(bankerResponse -> null != bankerResponse.getBankerId() && bankerResponse.getBankerId().equals(item.getBankerId())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(collect)) {
                        BankerResponse bankerResponse = collect.get(0);
                        re.setBankerName(bankerResponse.getBankerName());
                    }
                }

                //赋值物流最新状态
                String itemExpressNo = item.getExpressNo();
                String itemExpressCode = item.getExpressCode();
                String latestExpressState = "";
                if (request.getStatus()!=null && request.getStatus().equals(2)){
                    if (StringUtils.isNotEmpty(itemExpressNo) && StringUtils.isNotEmpty(itemExpressCode)) {
                        try {
                            List<YxExpressOrders> expressOrdersList = expressMap.get(itemExpressNo);
                            if (!CollectionUtils.isEmpty(expressOrdersList)) {
                                List<YxExpressOrders> curExpressList = expressOrdersList.stream().filter(e -> e.getCompanyNo().equals(itemExpressCode)).collect(Collectors.toList());
                                if(!CollectionUtils.isEmpty(curExpressList)){
                                    YxExpressOrders curExpress = curExpressList.stream().max(Comparator.comparingInt(YxExpressOrders::getId)).get();
                                    if (null != curExpress) {
                                        List<QueryTrackData> queryTrackDatas = JSON.parseArray(curExpress.getInfoText(), QueryTrackData.class);
                                        if(!CollectionUtils.isEmpty(queryTrackDatas)){
                                            QueryTrackData queryTrackData = queryTrackDatas.get(0);
                                            latestExpressState = queryTrackData.getFtime()+" "+ExpressEnums.getStatusName(curExpress.getStatus().toString());
                                            re.setLatestExpressState(latestExpressState);
                                        }
                                    }
                                }
                            }
                        } catch (Exception e) {
                            log.info("订单列表物流轨迹转换出错！{}", e);
                        }
                    }
                }else{
                    String lastExpressState= item.getIsRejection() == 1 ? "用户退回/退签/拒签/拒收" : "";
                    if(StringUtils.isNotEmpty(lastExpressState)){
                        re.setLatestExpressState(lastExpressState);
                    }else {
                        //设置签收时间
                        re.setLatestExpressState(item.getReceiveTime() != null ? DateUtil.dateToStr(item.getReceiveTime()) + " 已签收" : "");
                    }
                }

//            //供货价
//            if (!CollectionUtils.isEmpty(yxProductSpecs)) {
//                List<YxProductSpec> collect = yxProductSpecs.stream().filter(productSpec -> productSpec.getId().equals(item.getProductSpecId())).collect(Collectors.toList());
//                if (!CollectionUtils.isEmpty(collect)) {
//                    item.setSupplyPrice(collect.get(0).getSupplyPrice());
//                    item.setCostPrice(collect.get(0).getCostPrice());
//                }
//            }
//                String expressRecordStr = CollectionUtils.isEmpty(records)? "" :
//                        records.stream().filter(record -> record.getChildOrderNo().equals(item.getChildOrderNo()))
//                                .map(record -> ExpressDicUtil.getMapKey(record.getCompanyNo()) +":"+ record.getExpressEno()).collect(Collectors.joining("/"));
//                re.setExpressRecordStr(expressRecordStr);
//
//
//                re.setProductId(item.getProductId() == null ? "" :item.getProductId().toString());
                re.setOrderStatus(item.getOrderStatus() == null ? "" :OrderStatusEnums.getStatusDesc(item.getOrderStatus()));
//                re.setDeliverStatus(item.getDeliverStatus() == null ? "" :item.getDeliverStatus()==1 ? "是" : "否");
//                re.setIsZeroProduct(item.getIsZeroProduct() == null ? "" :item.getIsZeroProduct() == 1 ? "是" : "不是");
                re.setProductTotalMoney(Optional.ofNullable(item.getCostPrice()).orElse(BigDecimal.ZERO).add(Optional.ofNullable(item.getFreight()).orElse(BigDecimal.ZERO)).toString());
                re.setCostPrice(item.getCostPrice() == null ? "" :item.getCostPrice().toString());
                re.setFreight(item.getFreight() == null ? "" : item.getFreight().toString());

                //跟单备注
                if (!com.alibaba.excel.util.CollectionUtils.isEmpty(orderExceptionNotes)) {
                    List<OrderExceptionNoteResponse> notes = orderExceptionNotes.stream().filter(item2 -> re.getChildOrderNo().equals(item2.getChildOrderNo())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(notes)) {
                        re.setOrderExceptionNoteStr(notes.get(0).getAdminName()+ " " + notes.get(0).getContent() +
                                " 时间为"  + DateUtil.dateToStr(notes.get(0).getCreateTime()));
                    }

                }

                //处理商品规格
                if (StringUtils.isNotBlank(item.getProductSkuSpec())) {
                    String[] productSkuSpecList = item.getProductSkuSpec().split(",");
                    StringBuffer buffer = new StringBuffer();
                    for (String sku : productSkuSpecList) {
                        if (!sku.contains("颜色")) {
                            buffer.append(sku);
                        }
                    }
                    re.setProductSkuSpec(buffer.toString());
                }

                //显示收款公司
                String account = item.getAccount();
                if (StringUtils.isNotBlank(account)){
                    Map<String, String> accountMap = new HashMap<>();
                    accountMap.put("xxxx","xxxx");







                    re.setPayingMerchantName(accountMap.get(account));
                }


//                countDownLatch2.countDown();
                data.add(re);
            });
//            try {
//                countDownLatch2.await();
//            } catch (InterruptedException e) {
//                log.error("4-----组装订单信息错误{}", e);
//            }
            //如果为true,需要更新到处状态
//            if (flag){
//                List<String> collect = responses.stream().filter(item -> null != item.getIsExport() && item.getIsExport() == 0).map(SupplyChainImportOrdersResponse::getChildOrderNo).collect(Collectors.toList());
//                if (!CollectionUtils.isEmpty(collect)) {
//                    bankerOrderMapper.updateIsExportByChildOrderNoList(collect);
//                }
//
//            }
        }
        return data;
    }



    public List<String> queryReturnOrdersByBankerId(Integer bankerId) {
        Example example = new Example(YxOrders.class);
        example.createCriteria().andEqualTo("bankerId", bankerId);
        example.selectProperties("childOrderNo");
        List<YxOrders> list = ordersMapper.selectByExample(example);
        List<String> result = list.stream().map(YxOrders::getChildOrderNo).collect(Collectors.toList());
        return result;
    }

    public List<BankerOrderResponse> getBankerOrders(PlatformExportRequest request) {
        //先根据供应商id查order_info表的无效订单或退款订单的id拼接成订单号
//        List<String> orderInfoIdList =  ordersInfoDao.selectByBankerId();
//        List<String> returnGoodsListReturn = returnGoodsService.returningOrderList(request.getLevel().equals(0) ? null : request.getBankerId());//已退款的订单(包含退货申请中的订单)
//        orderInfoIdList.addAll(returnGoodsListReturn);
//        request.setOrderNoList(orderInfoIdList);//做过滤
        List<String> return_childOrderNo = queryReturnOrdersByBankerId(request.getBankerId());
        request.setOrderNoList(return_childOrderNo);

        String orderStatusStr = request.getOrderStatusStr();
        if (com.alibaba.excel.util.StringUtils.isEmpty(orderStatusStr)) {
            orderStatusStr = "0";
        }
        log.info("orderStatusStr={}", orderStatusStr);
        List<String> orderStatusList = Arrays.asList(orderStatusStr.split(","));
        request.setOrderstatus(orderStatusList);
        log.info("===request==={}", request.getOrderstatus());

        List<BankerOrderResponse> bankerOrderList = new ArrayList<>();
        try {
            String redisKey = "banker:orders:" + String.valueOf(request.hashCode());
            log.info("===redis key==={}", redisKey);
            String redisListStr = "";
            try {
                redisListStr = redisService.get(redisKey);
            } catch (Exception e) {
            }
            boolean saveRedisFlag = false;
            if (request.getLevel().equals(0) && !com.alibaba.excel.util.StringUtils.isEmpty(redisListStr)) {
                log.info("===命中缓存了===");
                bankerOrderList = JSONObject.parseArray(redisListStr, BankerOrderResponse.class);
            } else {
                bankerOrderList = bankerOrderMapper.getBankerOrderList(request);
                LocalDateTime ldt = LocalDateTime.now(ZoneId.systemDefault());
                if (ldt.getHour() > 14 && request.getLevel().equals(0)) {
                    saveRedisFlag = true;
                } else {
                    if (ldt.getHour() == 14 && ldt.getMinute() > 30 && request.getLevel().equals(0)) {
                        saveRedisFlag = true;
                    }
                }
                if (saveRedisFlag) {
                    String listJsonStr = JSONObject.toJSONString(bankerOrderList);
                    log.info("===redis key==={}", redisKey);
                    redisService.set(redisKey, listJsonStr);
                    redisService.expire(redisKey, 10 * 60);
                }
            }
        } catch (Exception e) {
            log.error("===查询缓存异常==={}", e);
            if (CollectionUtils.isEmpty(bankerOrderList)) {
                bankerOrderList = bankerOrderMapper.getBankerOrderList(request);
            }
        }

//        List<String> orderInfoIdListReturn = ordersInfoDao.selectByBankerId();//已退款的订单
//        List<String> returnGoodsList = returnGoodsService.returningOrderList(request.getLevel().equals(0) ? null : request.getBankerId());//已退款的订单(包含退货申请中的订单)
//        orderInfoIdListReturn.addAll(returnGoodsList);

        //过滤掉退款订单
        bankerOrderList = bankerOrderList.stream().filter(s -> !return_childOrderNo.contains(s.getOrderNo())).collect(Collectors.toList());

        return bankerOrderList.stream().map(item -> {
            String typeno = this.getTypeno(String.valueOf(item.getId()));
            item.setTypeno(typeno);
            //xxxx账号导出订单脱敏处理
            if (request.getBankerId() != null && 19 == request.getBankerId()) {
                int datediff = 0;
                try {
                    datediff = DateUtil.daysBetween(item.getCreateTime(), new Date());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                if (datediff > 45) {
                    item.setUserTel(DesensitizedUtil.desensitizedPhoneNumber(item.getUserTel()));
                    item.setUserName(DesensitizedUtil.desensitizedName(item.getUserName()));
                    item.setDeliveryAddress(DesensitizedUtil.desensitizedAddress(item.getDeliveryAddress()));
                } else {
                    item.setUserTel(item.getUserTel());
                    item.setUserName(item.getUserName());
                    item.setDeliveryAddress(item.getDeliveryAddress());
                }
            }
            return item;
        }).collect(Collectors.toList());
    }

    public String getBankerName(Integer bankerId) {
        YxBanker banker = bankerService.queryById(bankerId);
        if (null == banker) {
            return "";
        }
        return banker.getName();
    }

    public List<String> orderUpload(List<OrderUploadRequest> requestList) {
        AtomicReference<Integer> count = new AtomicReference<>(0);
        List<String> successData = new ArrayList<>();
        List<String> ignoreOrderUserNames = Arrays.asList(ignoreOrderUserName.split(","));
        requestList.stream().forEach(request -> {
            if (!CollectionUtils.isEmpty(ignoreOrderUserNames) && ignoreOrderUserNames.contains(request.getUserName())) {
                log.info("===ignore order user_name:{}===", request.getUserName());
                return;
            }
            RLock lock = redissonClient.getLock("ORDER_UPLOAD" + request.getChildOrderNo());
            boolean b = false;
            try {
                b = lock.tryLock(0, 5, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                lock.unlock();
            }
            if (!b) {
                throw new ApiException("正在上传供应链" + request.getChildOrderNo());
            }
            Example example = new Example(YxOrders.class);
            example.createCriteria().andEqualTo("childOrderNo", request.getChildOrderNo());
            List<YxOrders> yxOrdersList = ordersMapper.selectByExample(example);
            if (!CollectionUtils.isEmpty(yxOrdersList)) {
                return;
            }
            if (null != request.getOrdersPayDTO()){
                OrdersPayDTO ordersPayDTO = request.getOrdersPayDTO();
                Example ordersPayExample = new Example(YxOrdersPay.class);
                ordersPayExample.createCriteria().andEqualTo("orderNo", ordersPayDTO.getOrderNo());
                List<YxOrdersPay> yxOrdersPayList = ordersPayMapper.selectByExample(ordersPayExample);
                if (CollectionUtils.isEmpty(yxOrdersPayList)) {
                    YxOrdersPay yxOrdersPay = new YxOrdersPay();
                    BeanUtils.copyProperties(ordersPayDTO,yxOrdersPay);
                    if (null != yxOrdersPay.getId()) {
                        yxOrdersPay.setId(null);
                    }
                    if (StringUtils.isNotBlank(yxOrdersPay.getResText())){
                        try {
                            Map map = JSONObject.parseObject(yxOrdersPay.getResText(), Map.class);
                            String transactionId = (String) map.get("transactionId");
                            yxOrdersPay.setResText(transactionId);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    try {
                        yxOrdersPay.setChildOrderNo(request.getChildOrderNo());
                        ordersPayMapper.insertSelective(yxOrdersPay);
                    } catch (Exception e) {
                        log.error("===供应链插入orders_pay表异常==={}", e);
                    }
                }
            }
            YxProduct yxProduct = productMapper.selectByPrimaryKey(request.getProductId());
            YxProductSpec yxProductSpec = productSpecMapper.selectByPrimaryKey(request.getProductSpecId());
            request.setBankerProductId(yxProduct.getBankerProductId());
            request.setBankerProductSpecId(yxProductSpec.getSupplyId());
            request.setBankerId(yxProduct.getBankerId());

            YxOrders yxOrders = new YxOrders();
            BeanUtils.copyProperties(request, yxOrders);
            if(StringUtils.isNotBlank(request.getAuthenticatedCard())){
                yxOrders.setIsExit(2);
            }else {
                yxOrders.setIsExit(1);
            }
            yxOrders.setProductName(yxProduct.getProductName() + "(" + yxProductSpec.getSkuSpec() + ")");
            yxOrders.setOrderStatus(1);
            if (null == yxOrders.getProductSum() || yxOrders.getProductSum() <= 1) {
                yxOrders.setProductPrice(yxProductSpec.getSupplyPrice());
                yxOrders.setCostPrice(yxProductSpec.getCostPrice());
            }else {
                yxOrders.setProductPrice(yxProductSpec.getSupplyPrice().multiply(BigDecimal.valueOf(yxOrders.getProductSum().longValue())));
                yxOrders.setCostPrice(null == yxProductSpec.getCostPrice() ? new BigDecimal(0) : yxProductSpec.getCostPrice().multiply(BigDecimal.valueOf(yxOrders.getProductSum())));
            }
            //计算集采价格
            yxOrders = calculationProductSumGreaterOne(yxOrders, yxProduct.getBankerProductId());
            //计算运费
            YxBankerProduct yxBankerProduct = bankerProductMapper.selectByPrimaryKey(request.getBankerProductId());
            if (null!=yxBankerProduct.getFreightId()){
                yxOrders.setFreight(calculateFreight(yxBankerProduct.getFreightId(),request.getProductSum(),request.getCity(),request.getProvince()));
            }else {
                yxOrders.setFreight(new BigDecimal(0));
            }
            int insert = ordersMapper.insert(yxOrders);
            //保存供应商
            request.setProductName(yxOrders.getProductName());
            request.setBankerProductId(yxProduct.getBankerProductId());
            request.setBankerProductSpecId(yxProductSpec.getSupplyId());
            request.setProductPrice(yxOrders.getCostPrice());// todo 传到供应商订单的价格
            request.setFreight(yxOrders.getFreight());
            //保存订单数据到供应商
            OrdersToBankerOrder(request,yxOrders);
            count.set(count.get() + insert);
            if (null != lock) {
                lock.unlock();
            }
            List<String> childOrderNos = Collections.singletonList(request.getChildOrderNo());
            successData.add(request.getChildOrderNo());
            try {
                //发送订单信息到kafka
//                getOrderMsg(childOrderNos);
                orderSendKafkaRecordMapper.insertBatch(childOrderNos,0,0);
                log.info("=========发送订单信息到kafka=========：{}",childOrderNos);
            } catch (Exception e) {
                log.error("=========发送订单信息到kafka异常=========：{}",childOrderNos);
            }
        });
        redisService.set("batch_task_finish", "1");
        return successData;
    }

    /**
     * 计算运费
     */
    private BigDecimal calculateFreight(Integer freightId, Integer productNum, String city,String province) {
        if ("市辖区".equals(city)){
            city = province;
        }
        AtomicReference<BigDecimal> freight = new AtomicReference<>(BigDecimal.ZERO);
        if (null != freightId){
            FreightTemplateResponse freightTemplateResponse = productService.findFreightTemplateResponseById(freightId);
            log.info("========查询到的运费模板========productId:{},freightTemplateResponse:{}", freightTemplateResponse, freightTemplateResponse);
            if (null != freightTemplateResponse && freightTemplateResponse.getFreightWay() != null) {
                if (freightTemplateResponse.getFreightWay() == 0) {
                    List<YxAssignFreightResponse> assignFreightList = freightTemplateResponse.getAssignFreightList();
                    AtomicReference<Boolean> flag = new AtomicReference<>(false);//记录是否符合自定义模板地区

                    if (!flag.get()) {
                        String finalCity = city;
                        assignFreightList.stream().filter(assignFreight -> StringUtils.isNotEmpty(assignFreight.getRegion())).forEach(assignFreight -> {
                            String[] split = assignFreight.getRegion().split(",");
                            Optional<String> frist = Stream.of(split).filter(x -> x.equals(finalCity)).findFirst();
                            String[] provinceSplit = assignFreight.getRegionDesc().split(",");
                            Optional<String> provincefrist = Stream.of(provinceSplit).filter(x -> x.contains("[全境]") && province.equals(x.replace("[全境]",""))).findFirst();
                            //如果存在
                            if ((frist.isPresent() && StringUtils.isNotBlank(frist.get()))
                                    || (provincefrist.isPresent() && StringUtils.isNotBlank(provincefrist.get()))) {
                                if (productNum <= assignFreight.getAmount()) {
                                    freight.set(assignFreight.getFreight());//如果只有一件商品,订单运费 = 模板运费
                                    flag.set(true);
                                } else {
                                    freight.set(assignFreight.getFreight()
                                            .add(assignFreight.getRenew()
                                                    .multiply(new BigDecimal(productNum - assignFreight.getAmount()))));  //如果有多件,订单运费=模板运费+续件数*续件运费
                                    flag.set(true);
                                }
                            }

                        });
                    }
                    if (!flag.get()) {
                        if (productNum <= freightTemplateResponse.getAmount()) {
                            freight.set(freightTemplateResponse.getFreight());//如果只有一件商品,订单运费 = 模板运费
                        } else {
                            freight.set(freightTemplateResponse.getFreight()
                                    .add(freightTemplateResponse.getRenew()
                                            .multiply(new BigDecimal(productNum - freightTemplateResponse.getAmount()))));  //如果有多件,订单运费=模板运费+续件数*续件运费
                        }
                    }
                } else if (freightTemplateResponse.getFreightWay() == 1){
                    freight.set(freightTemplateResponse.getFreight().multiply(new BigDecimal(productNum)));//如果只有一件商品,订单运费 = 模板运费
                }else {
                    freight.set(new BigDecimal(0));
                }
            }
            return freight.get();
        }
        return freight.get();
    }

    private YxOrders calculationProductSumGreaterOne(YxOrders yxOrders, Integer bankerProductId) {
        log.info("===计算集采价==={}, {}，{}", yxOrders.getChildOrderNo(), yxOrders.getProductSum(), bankerProductId);
        if (null == yxOrders.getProductSum() || yxOrders.getProductSum() <= 1) {
            return yxOrders;
        }
        String order_spec = yxOrders.getProductSkuSpec();
        if (StringUtils.isEmpty(order_spec)) {
            return yxOrders;
        }
        Example example = new Example(YxBankerProductSpec.class);
        example.createCriteria().andEqualTo("productId", bankerProductId).andEqualTo("status", 1);
        List<YxBankerProductSpec> bankerProductSpecList = bankerProductSpecMapper.selectByExample(example);

        final BigDecimal[] costPrice = {BigDecimal.ZERO};
        String[] order_spec_arr = order_spec.split("\\|");
        Arrays.stream(order_spec_arr).forEach(item -> {
            log.info("===规格值==={}", item);
            String[] skuSpecs = item.split("\\*");
            if (1 == skuSpecs.length) {
                return;
            }
            String specName = item.split("\\*")[0];//规格名称
            String productSumStr = item.split("\\*")[1];//购买量（可能包含单位）
            if (StringUtils.isEmpty(productSumStr)) {
                return;
            }
            String regEx="[^0-9]";
            Pattern p = Pattern.compile(regEx);
            Matcher m = p.matcher(productSumStr);
            String productSumStrNoUnit =  m.replaceAll("").trim();//去掉带单位的情况（比如3斤，3袋等）
            Integer productSum = Integer.parseInt(productSumStrNoUnit);//实际购买量
            log.info("===实际购买量==={}", productSum);
            if (null == productSum || productSum <= 1) {
                return;
            }

            //根据规格名称来匹配供应商规格
            List<YxBankerProductSpec> matchProductSpecList =
                    bankerProductSpecList.stream().filter(productSpec -> productSpec.getSkuSpec().equals(specName)).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(matchProductSpecList)) {
                return;
            }
            YxBankerProductSpec matchProductSpec = matchProductSpecList.get(0);
            log.info("===匹配中的规格==={}", matchProductSpec);
            //开始查询是否有集采规则
            BigDecimal batchPrice = doProductBatchRule(bankerProductId, matchProductSpec.getId(), productSum);

            if (null != batchPrice) {
                costPrice[0] = costPrice[0].add(batchPrice.multiply(BigDecimal.valueOf(productSum)));
            }
        });
        if (costPrice[0].compareTo(BigDecimal.ZERO) > 0) {
            yxOrders.setCostPrice(costPrice[0]);
        }
        return yxOrders;
    }

    /**
     * 计算商品数量大于1时的团购价
     * @param yxOrders          订单信息
     * @param bankerProductId   供应商商品id
     * @param ordersSpecNumList 订单规格数量（这里的规格是供应链的规格）
     *                          所以后面的逻辑中，需要根据供应链的规格得到供应商商品的规格
     * @return
     */
    private YxOrders calculationProductSumGreaterOne(YxOrders yxOrders, Integer bankerProductId, List<YxOrdersSpec> ordersSpecNumList) {
        log.info("===计算集采价==={}, {}，{}", yxOrders.getChildOrderNo(), yxOrders.getProductSum(), bankerProductId);
        if (null == yxOrders.getProductSum() || yxOrders.getProductSum() <= 1) {
            return yxOrders;
        }

        if (CollectionUtils.isEmpty(ordersSpecNumList)) {
            return yxOrders;
        }
        //得到供应商商品规格集合
        Example example = new Example(YxBankerProductSpec.class);
        example.createCriteria().andEqualTo("productId", bankerProductId).andEqualTo("status", 1);
        List<YxBankerProductSpec> bankerProductSpecList = bankerProductSpecMapper.selectByExample(example);
        // 得到供应商商品设置的集采规则
        Example batchRuleExample = new Example(YxProductBatchRule.class);
        batchRuleExample.createCriteria().andEqualTo("productId", bankerProductId).andEqualTo("status", 1);
        List<YxProductBatchRule> batchRuleList = productBatchRuleMapper.selectByExample(batchRuleExample);
        if (CollectionUtils.isEmpty(batchRuleList)) {
            log.debug("=========return 1===============");
            return yxOrders;
        }
        // 得到供应商商品设置的集采价集合
        Example batchPriceExample = new Example(YxProductBatchPrice.class);
        batchPriceExample.createCriteria().andEqualTo("productId", bankerProductId).andEqualTo("status", 1);
        List<YxProductBatchPrice> batchPriceList = productBatchPriceMapper.selectByExample(batchPriceExample);
        if (CollectionUtils.isEmpty(batchPriceList)) {
            return yxOrders;
        }

        final BigDecimal[] costPrice = {BigDecimal.ZERO};
        ordersSpecNumList.stream().forEach(item -> {
            Example productSpecExample = new Example(YxProductSpec.class);
            productSpecExample.createCriteria().andEqualTo("id", item.getSpecId());
            YxProductSpec productSpec = productSpecMapper.selectOneByExample(productSpecExample);
            //单个的成本价
            BigDecimal costPriceSingle = productSpec.getCostPrice();
            if (null == productSpec) {
                costPrice[0] = costPrice[0].add(costPriceSingle);
                log.debug("=========return 2===============");
                return;
            }

            //得到供应链规格id指向的供应商商品规格
            List<YxBankerProductSpec> matchBankerProductSpecList = bankerProductSpecList.stream().filter(bankerProductSpec -> bankerProductSpec.getId().equals(productSpec.getSupplyId())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(matchBankerProductSpecList)) {
                costPrice[0] = costPrice[0].add(costPriceSingle);
                log.debug("=========return 3===============");
                return;
            }
            YxBankerProductSpec bankerProductSpec_match = matchBankerProductSpecList.get(0);
            //
            List<YxProductBatchRule> matchBatchRuleList = batchRuleList.stream().filter(rule -> rule.getMax() >= item.getSpecNum() && rule.getMin() <= item.getSpecNum()).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(matchBatchRuleList)) {
                costPrice[0] = costPrice[0].add(costPriceSingle);
                log.debug("=========return 4===============");
                return;
            }
            YxProductBatchRule productBatchRule = matchBatchRuleList.get(0);
            List<YxProductBatchPrice> yxProductBatchPriceList =
                    batchPriceList.stream().filter(batchPrice -> batchPrice.getBatchRuleId().equals(productBatchRule.getId()) && batchPrice.getSpecId().equals(bankerProductSpec_match.getId())).collect(Collectors.toList());

            if (CollectionUtils.isEmpty(yxProductBatchPriceList)) {
                costPrice[0] = costPrice[0].add(costPriceSingle);
                log.debug("=========return 5===============");
                return;
            }
            costPrice[0] = costPrice[0].add(yxProductBatchPriceList.get(0).getPrice().multiply(BigDecimal.valueOf(item.getSpecNum())));
        });

        if (costPrice[0].compareTo(BigDecimal.ZERO) > 0) {
            yxOrders.setCostPrice(costPrice[0]);
        }
        return yxOrders;
    }

    /**
     * 获取集采的价格
     * @param productId  供应商商品id
     * @param specId     供应商商品规格id
     * @param productSum 购买数量
     * @return 返回集采价格
     */
    private BigDecimal doProductBatchRule(Integer productId, Integer specId, Integer productSum) {
        log.info("===doProductBatchRule==={},{},{}", productId, specId, productSum);
        Example example = new Example(YxProductBatchRule.class);
        //查询采集规则：商品id + 规则区间内 + 有效状态
        example.createCriteria().andEqualTo("productId", productId)
                .andLessThanOrEqualTo("min", productSum)
                .andGreaterThanOrEqualTo("max", productSum)
                .andEqualTo("status", 1);
        List<YxProductBatchRule> batchRuleList = productBatchRuleMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(batchRuleList)) {
            //如果商品数量不在规则区间，则查询购买数量大于规则外的规则
            example = new Example(YxProductBatchRule.class);
            example.createCriteria().andEqualTo("productId", productId)
                    .andLessThanOrEqualTo("max", productSum).andEqualTo("status", 1);
            example.orderBy("max").desc();
            batchRuleList = productBatchRuleMapper.selectByExample(example);
            if (CollectionUtils.isEmpty(batchRuleList)) {
                return null;
            }
        }
        YxProductBatchRule batchRule = batchRuleList.get(0);
        log.info("===batchRule==={}", batchRule);

        Example batchPriceExample = new Example(YxProductBatchPrice.class);
        batchPriceExample.createCriteria().andEqualTo("productId", productId)
                .andEqualTo("batchRuleId", batchRule.getId())
                .andEqualTo("specId", specId)
                .andEqualTo("status", 1);
        List<YxProductBatchPrice> batchPriceList = productBatchPriceMapper.selectByExample(batchPriceExample);
        if (CollectionUtils.isEmpty(batchPriceList)) {
            return null;
        }
        log.info("===集采价格==={}", batchPriceList.get(0).getPrice());
        return batchPriceList.get(0).getPrice();
    }

    private void sendJushuitan(String bankerId, List<request.OrderUploadRequest> requestsNew) {
        if (CollectionUtils.isEmpty(requestsNew)) {
            return;
        }
        try {
            String redisConstant = RedisConstants.OUT_ERP_KEY;
            String partnerId = stringRedisTemplate.opsForValue().get(redisConstant + "partnerId:" + bankerId);
            String partnerKey = stringRedisTemplate.opsForValue().get(redisConstant + "partnerKey:" + bankerId);
            String token = stringRedisTemplate.opsForValue().get(redisConstant + "token:" + bankerId);
            OrderAction orderAction = new OrderAction(partnerId, partnerKey, token, sHostUrl);
            String result = orderAction.orderUploadResultIsStr(requestsNew);
            log.info("===jushuitan result==={}", result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            JunshuitanRsponseDto dto = JSONObject.toJavaObject(jsonObject, JunshuitanRsponseDto.class);
            log.info("===订单发送聚水潭响应信息:{}", result);
            if (dto.getCode() != 0) {
                log.info("===订单发送聚水潭失败, 返回参数:{}", dto);
                String rspMsg = "code=" + dto.getCode() + ", msg=" + dto.getMsg();
                saveUploadOrderFailInfo(requestsNew, 0, rspMsg);
                return;
            }
            saveUploadOrderFailInfo(requestsNew, 1, null);
            log.info("===订单发送聚水潭成功===");
        } catch (Exception e) {
            log.error("===订单发送聚水潭接口异常,{}", e);
        }
    }

    /**
     * 保存上传聚水潭订单数据
     *
     * @param requests
     * @param status   状态 1-上传成功  0-上传失败
     */
    private void saveUploadOrderFailInfo(List<request.OrderUploadRequest> requests, Integer status, String rspMsg) {
        List<YxUploadOrderJst> waitSaveObjs = new ArrayList<>();
        List<String> orderNos = requests.stream().map(s -> s.getSo_id()).collect(Collectors.toList());
        Example example = new Example(YxBankerOrder.class);
        example.createCriteria().andIn("orderNo", orderNos);
        List<YxBankerOrder> bankerOrderList = bankerOrderMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(bankerOrderList)) {
            bankerOrderList.stream().forEach(s -> {
                s.setUploadFlag(new Byte(status.toString()));
                bankerOrderMapper.updateByPrimaryKeySelective(s);
            });
        }

        requests.stream().forEach(s -> {
            Example jst_example = new Example(YxUploadOrderJst.class);
            jst_example.createCriteria().andEqualTo("orderNo", s.getSo_id());
            YxUploadOrderJst oldJst = uploadOrderJstService.selectOneByExample(jst_example);
            if (null != oldJst && null != oldJst.getId()) {
                oldJst.setStatus(status);
                oldJst.setRspMsg(rspMsg);
            } else {
                oldJst = YxUploadOrderJst.builder()
                        .orderNo(s.getSo_id())
                        .status(status)
                        .rspMsg(rspMsg)
                        .createTime(new Date())
                        .build();
            }

            waitSaveObjs.add(oldJst);
        });
        if (!CollectionUtils.isEmpty(waitSaveObjs)) {
            uploadOrderJstService.saveBatchByPrimaryKeySelective(waitSaveObjs);
        }
    }

    public static void main2(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Double otherAmount = new Double("0.00");
        Map<String, Object> jsonMap = new HashMap<String, Object>();
        jsonMap.put("orderNo", "Q202112164523546");
        jsonMap.put("ebpCode", "4403961UMP");// 电商平台代码
        jsonMap.put("ebpName", "深圳市一探究竟科技有限公司");// 电商平台名称
        jsonMap.put("ebcCode", "4408W61005");// 电商企业代码
        jsonMap.put("ebcName", "广东良无限实业有限公司");// 电商企业名称
        jsonMap.put("goodsValue", "60");// todo 需要验证金额正确性
        jsonMap.put("freight", otherAmount);
        jsonMap.put("discount", otherAmount);
        jsonMap.put("taxTotal", otherAmount);
        jsonMap.put("actualPaid", "60");
        jsonMap.put("currency", "142");
        jsonMap.put("buyerRegNo", "111");
        jsonMap.put("buyerName", "测试1");
        jsonMap.put("buyerTelephone", "18873058010");
        jsonMap.put("buyerIdType", "1");
        jsonMap.put("buyerIdNumber", "421023198902278512");
        jsonMap.put("payCode", "4403169D3W");
        jsonMap.put("payName", "财付通支付科技有限公司");
        jsonMap.put("payTransactionId", "test");
        jsonMap.put("consignee", "测试1");
        jsonMap.put("consigneeTelephone", "18873058010");
        jsonMap.put("consigneeAddress", "广东省深圳市宝安区定军山大厦");
        jsonMap.put("consigneeDistrict", getDistrict("广东省", "深圳市", "宝安区"));

        jsonMap.put("province", "广东省");
        jsonMap.put("city", "深圳市");
        jsonMap.put("town", "宝安区");

        jsonMap.put("note", "测试");
        jsonMap.put("batchNo", String.valueOf(System.currentTimeMillis()));
        jsonMap.put("createTime", sdf.format(new Date()));
        jsonMap.put("tradeMode", "1210");
        jsonMap.put("storeId", "1481");
        jsonMap.put("merchantId", "100012");// 商户代码

        List<JSONObject> orderItems = new LinkedList();
        JSONObject orderItem = new JSONObject();
        orderItem.put("gnum", "1");
        orderItem.put("itemNo", "2022022001");
        orderItem.put("itemName", "测试商品");
        orderItem.put("gmodel", "测试规格");
        orderItem.put("itemDescribe", "测试");
        orderItem.put("unit", "122");
        orderItem.put("qty", 1);
        orderItem.put("price", "60");
        orderItem.put("totalPrice", "60");
        orderItem.put("currency", "142");
        orderItem.put("country", "106");
        orderItem.put("note", "测试");
        //orderItem.put("tradeCountry", "110");// 贸易国编码
        orderItems.add(orderItem);

        jsonMap.put("orderItems", orderItems);

        String json = JSON.toJSONString(jsonMap);
        try {
//            String dataStr = Base64.getEncoder().encodeToString(json.getBytes("utf-8"));
            json = URLEncoder.encode(json, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        Map<String, Object> param = new HashMap<String, Object>();
        param.put("name", "wms.order.add");
        param.put("app_key", "100012");//wmsAppKey
        param.put("data", json);
        param.put("timestamp", sdf.format(new Date()));
        param.put("version", "1.0");
        // param.put("access_token", "");
        try {
            String sign = WMSUtil.buildSign(param, "8ddcff3a80f4189ca1c9d4d902c3c909");//wmsSecret
            param.put("sign", sign);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String postJson = JSON.toJSONString(param);
        log.info("===wms推送请求参数：{}====", postJson);
        String resp = HttpClientUtil.doPostJson("https://open.gimicb.com/api", postJson);
        log.info("===处理上传WMS返回结果：{}=====", resp);
    }

    /**
     * 售后订单上传wms系统
     * @return
     */
    public boolean handleToWMSByReturnGoods(String orderNo, String reason, Integer storeId, String note) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("orderType", "I");
        jsonObject.put("orderNo", orderNo);
        jsonObject.put("reason", reason);
        jsonObject.put("storeId", String.valueOf(storeId));
        jsonObject.put("merchantId", wmsPlatformConfig.getMerchantId());
        jsonObject.put("note", note);

        String jsonStr = null;
        try {
//            String dataStr = Base64.getEncoder().encodeToString(json.getBytes("utf-8"));
            jsonStr = URLEncoder.encode(jsonObject.toJSONString(), "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String resp = WMS_Request(jsonStr, "wms.order.refund");

        Map<String, Object> resultMap = JSONObject.parseObject(resp, Map.class);
        String lgOrderNo = null == resultMap.get("otherSysOrderNo") ? "" : resultMap.get("otherSysOrderNo").toString();
        String code = String.valueOf(resultMap.get("code"));
        if (!"0".equals(code)) {
            log.info("===上传WMS售后订单失败，需要作登记处理==={}", orderNo);
            String messageText = String
                    .format(template, "跨境订单上传失败告警",
                            "supplychain-api", "order.upload_return_goods_wms",
                            "500", "跨境订单异常_WMS",
                            "",
                            JSONObject.toJSONString("境外退款订单上传双子供应链WMS异常，子订单号：" + orderNo));
            DingDingWebHookUtil.pushInfoToDingding(messageText, kuajing_accessToken);
            return false;
        }
        // 成功记录到mysql
        saveWmsOrderAddRecord(orderNo, lgOrderNo, "WMS", AbroadOrderPushTypeEnum.RETURN.getCode());
        return true;
    }

    /**
     * 处理上传LINK-订单新增
     * @param request
     * @return
     */
    public boolean handleToLINK(AbroadOrderDto request) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (!checkIsUploadToOtherSystem(request.getOrderNo())) {
            log.debug("===订单编号：{}已上传过LINK平台系统===", request.getOrderNo());
            return false;
        }
        // 报文内容不加密，只做MD5摘要签名
        OrderUploadLinkRequest jsonObj = new OrderUploadLinkRequest();
        jsonObj.setExternalOrderId(request.getOrderNo());
        jsonObj.setUserId(request.getOwnerUserId());
        jsonObj.setBusinessUnitId(request.getBusinessUnitId());
        jsonObj.setShopNick(request.getExternalShopName());
        //todo 渠道编码 可在https://www.yuque.com/docs/share/8a867b09-4823-4136-b653-f4b423eae65e?#Koup进行查询
        jsonObj.setOrderSource(request.getOrderSource());
        jsonObj.setOrderType("01");
        jsonObj.setStoreCode(request.getStoreCode());//测试时提供的数据
        jsonObj.setPostFee(request.getFreight().multiply(new BigDecimal(100)).longValue());
        jsonObj.setCurrency("CNY");
        jsonObj.setBuyerName(request.getBuyerName());
        jsonObj.setBuyerId(request.getBuyerRegNo());
        jsonObj.setBuyerIDType(1);
        jsonObj.setBuyerIDNo(request.getBuyerIdNumber());
        jsonObj.setPayType(parsePayName(request.getPayName()));
        jsonObj.setPayOrderId(request.getPayTransactionId());
        jsonObj.setBuyTime(sdf.format(request.getOrderTime()));
        jsonObj.setPayTime(sdf.format(request.getTradingTime()));
        jsonObj.setMessage(request.getNote());

        jsonObj.setDutiablePrice(request.getOriginalPrice().longValue() * 100 + (request.getFreight().longValue() * 100));
        jsonObj.setCustomsTax(0);
        jsonObj.setConsumptionTax(0);
        jsonObj.setVAT(0);
        jsonObj.setTotalTax(0);
        jsonObj.setInsurance(0);
        jsonObj.setCoupon(request.getOriginalPrice().subtract(request.getTotalAmount()).longValue() * 100);
        //买家实付金额
        jsonObj.setActualpayment(request.getTotalAmount().add(request.getFreight()).longValue() * 100);
        jsonObj.setGoodsList(generateGoodsList(request));
        jsonObj.setReceiverContact(generateReceiverContact(request));
        jsonObj.setSenderContact(generateSenderContact(request));
        jsonObj.setRefunderContact(generateSenderContact(request));

        //上报订单至LINK平台
        String resp = LINK_Request(JSONObject.toJSONString(jsonObj),
                LinkPlatformMethodEnum.ADD.getCode(),
                request.getCode(),
                request.getSecretKey());
        log.info("===order upload resp:{}", resp);
        Map<String, Object> resultMap = JSONObject.parseObject(resp, Map.class);
        String success = String.valueOf(resultMap.get("success"));
        if (!"true".equals(success)) {
            log.info("===上传LINK失败，需要作登记处理==={}", request.getOrderNo());
            String messageText = String
                    .format(template, "跨境订单上传失败告警",
                            "supplychain-api", "order.upload_order_link",
                            "500", "跨境订单异常_LINK",
                            "",
                            JSONObject.toJSONString("境外订单上传菜鸟供应链LINK异常，子订单号：" + request.getOrderNo()));
            DingDingWebHookUtil.pushInfoToDingding(messageText, kuajing_accessToken);
            return false;
        }
        saveWmsOrderAddRecord(request.getOrderNo(), resultMap.get("lgorderCode").toString(), "LINK", AbroadOrderPushTypeEnum.ADD.getCode());
        return true;
    }

    private Contact generateSenderContact(AbroadOrderDto request) {
        Contact contact = Contact.builder()
                .contactName(request.getLinkman())
                .zipCode("")
                .address("发货仓地址")
                .country("CN")
                .province("广东省")
                .mobilePhone("15907301025")
                .build();
        return contact;
    }

    private Contact generateReceiverContact(AbroadOrderDto request) {
        Contact contact = Contact.builder()
                .contactName(request.getBuyerName())
                .zipCode("")
                .address(request.getConsigneeAddress())
                .country("CN")
                .province(request.getProvince())
                .city(request.getCity())
                .district(request.getArea())
                .mobilePhone("15907301025")
                .build();
        return contact;
    }

    private List<Goods> generateGoodsList(AbroadOrderDto request) {
        Goods goods = Goods.builder()
                .itemId(request.getThreeSkuId())
                .extItemId(String.valueOf(request.getBankerProductId()))
                .subTradeId(request.getOrderNo())
                .goodsQuantity(request.getProductSum())
                .goodsTotalPrice(request.getOriginalPrice().longValue() * 100)
                .goodsTotalActualPrice(request.getTotalAmount().longValue() * 100)
                .goodsCustomsTax(0L)
                .goodsConsumptionTax(0L)
                .goodsVAT(0L)
                .goodsTotalTax(0L)
                .build();
        List<Goods> list = Arrays.asList(goods);
        return list;
    }

    private String parsePayName(String payName) {
        if (StringUtils.isNotEmpty(payName) && payName.indexOf("财付通") >= 0) {
            return "02";
        }
        return "01";
    }

    /**
     * 通关申报信息，跨境场景必填
     * @param request
     * @return
     */
    private CustomsDeclareInfo generateCustomsDeclareInfo(AbroadOrderDto request) {
        CustomsDeclareInfo customsDeclareInfo = CustomsDeclareInfo.builder()
                .buyerName(request.getBuyerName())
                .buyerPlatformId("")// todo 买家交易平台id
                .buyerIDType("1")
                .buyerIDNo(request.getBuyerIdNumber())
                .payerId("")// todo 支付人账号
                .payChannel(request.getPayCode())// todo 这里可能需要转译
                .payOrderId(request.getPayTransactionId())
                .nationality("CN")
                .contactNo(request.getBuyerTelephone())
                .build();
        return customsDeclareInfo;
    }

    /**
     * LINK组装订单金额信息
     * @param request
     * @return
     */
    private OrderAmountInfo generateOrderAmountInfo(AbroadOrderDto request) {
        OrderAmountInfo orderAmountInfo = OrderAmountInfo.builder()
                .actualPayment(request.getTotalAmount().longValue() * 100)
                .postFee(0)
                .currency("CNY")
                .build();
        return orderAmountInfo;
    }

    /**
     * LINK组装订单商品列表
     * @param request
     * @return
     */
    private List<OrderItem> generateOrderItemList(AbroadOrderDto request) {
        OrderItem orderItem = OrderItem.builder()
                .itemId(request.getThreeSkuId())
                .extItemId(String.valueOf(request.getBankerProductId()))
                .itemQuantity(1)
                .declareInfo(generateDeclareInfo(request))
                .isGift("0")
                .individualDelivery("0")
                .build();
        List<OrderItem> orderItems = Arrays.asList(orderItem);
        return orderItems;
    }

    private DeclareInfo generateDeclareInfo(AbroadOrderDto request) {
        DeclareInfo decl = DeclareInfo.builder()
                .itemTotalPrice(request.getTotalAmount().longValue() * 100)
                .itemTotalActualPrice(request.getTotalAmount().longValue() * 100)
                .firstQuantity(String.valueOf(request.getProductSum()))
                .firstUnit(request.getUnitCode())
                .itemPrice(request.getTotalAmount().longValue() * 100)
                .build();
        return decl;
    }

    /**
     * LINK组装收货方信息
     * @param request
     * @return
     */
    private ReceiverInfo generateReceiverInfo(AbroadOrderDto request) {
        ReceiverInfo receiverInfo = ReceiverInfo.builder()
                .country("CN")
                .province(request.getProvince())
                .city(request.getCity())
                .district(request.getArea())
                .address(request.getConsigneeAddress())
                .name(request.getBuyerName())
                .contactNo(request.getBuyerTelephone())
                .build();
        return receiverInfo;
    }

    private boolean checkIsUploadToOtherSystem(String orderNo) {
        Example haveExample = new Example(YxAbroadOrderRecord.class);
        haveExample.createCriteria().andEqualTo("orderNo", orderNo)
                .andEqualTo("type", AbroadOrderPushTypeEnum.ADD.getCode());
        int count = abroadOrderRecordMapper.selectCountByExample(haveExample);
        if (count > 0) {
            log.info("===订单编号：{}已上传过跨境仓储系统===", orderNo);
            return false;
        }
        return true;
    }

    //处理上传wms
    public boolean handleToWMS(AbroadOrderDto request) {
        if (!checkIsUploadToOtherSystem(request.getOrderNo())) {
            log.info("===订单编号：{}已上传过wms平台系统===", request.getOrderNo());
            return false;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Double otherAmount = new Double("0.00");
        Map<String, Object> jsonMap = new HashMap<String, Object>();
        jsonMap.put("orderNo", request.getOrderNo());
        jsonMap.put("ebpCode", wmsPlatformConfig.ebpCode);// 电商平台代码
        jsonMap.put("ebpName", wmsPlatformConfig.ebpName);// 电商平台名称
        jsonMap.put("ebcCode", wmsPlatformConfig.getEbcCode());// 电商企业代码
        jsonMap.put("ebcName", wmsPlatformConfig.getEbcName());// 电商企业名称
        jsonMap.put("goodsValue", request.getTotalAmount());// todo 需要验证金额正确性
        jsonMap.put("freight", otherAmount);
        jsonMap.put("discount", otherAmount);
        jsonMap.put("taxTotal", otherAmount);
        jsonMap.put("actualPaid", request.getTotalAmount());
        jsonMap.put("currency", "142");
        jsonMap.put("buyerRegNo", request.getBuyerRegNo());
        jsonMap.put("buyerName", request.getBuyerName());
        jsonMap.put("buyerTelephone", request.getBuyerTelephone());
        jsonMap.put("buyerIdType", "1");
        jsonMap.put("buyerIdNumber", request.getBuyerIdNumber());
        jsonMap.put("payCode", request.getPayCode());
        jsonMap.put("payName", request.getPayName());
        jsonMap.put("payTransactionId", request.getPayTransactionId());
        jsonMap.put("consignee", request.getConsignee());
        jsonMap.put("consigneeTelephone", request.getConsigneeTelephone());
        jsonMap.put("consigneeAddress", request.getConsigneeAddress());
        jsonMap.put("province", request.getProvince());
        jsonMap.put("city", request.getCity());
        jsonMap.put("town", request.getArea());
        jsonMap.put("consigneeDistrict", getDistrict(request.getProvince(), request.getCity(), request.getArea()));
        jsonMap.put("note", request.getNote());
        jsonMap.put("batchNo", String.valueOf(System.currentTimeMillis()));
        jsonMap.put("createTime", sdf.format(request.getOrderTime()));
        jsonMap.put("tradeMode", "1210");
        jsonMap.put("storeId", request.getBankerId());
        jsonMap.put("merchantId", wmsPlatformConfig.getMerchantId());// 商户代码

        List<JSONObject> orderItems = new LinkedList();
        Example example = new Example(CebOrderGoodsinfo.class);
        example.createCriteria().andEqualTo("orderId", request.getCebOrderId());
        List<CebOrderGoodsinfo> cebOrderGoodsinfos = cebOrderGoodsinfoMapper.selectByExample(example);
        AtomicInteger num = new AtomicInteger(1);
        cebOrderGoodsinfos.stream().forEach(item -> {
            JSONObject orderItem = new JSONObject();
            orderItem.put("gnum", num.getAndIncrement());
            orderItem.put("itemNo", request.getThreeSkuId());
            orderItem.put("itemName", item.getItemName());
            orderItem.put("gmodel", item.getGmodel());
            orderItem.put("itemDescribe", item.getItemDescribe());
            orderItem.put("unit", item.getUnit());
            orderItem.put("qty", item.getQty());
            orderItem.put("price", item.getPrice());
            orderItem.put("totalPrice", item.getTotalPrice());
            orderItem.put("currency", item.getCurrency());
            orderItem.put("country", item.getCountry());
            orderItem.put("note", item.getNote());
            //orderItem.put("tradeCountry", "110");// 贸易国编码
            orderItem.put("url", item.getItemLink());
            orderItems.add(orderItem);
        });
        jsonMap.put("orderItems", orderItems);

        String json = JSON.toJSONString(jsonMap);
        try {
//            String dataStr = Base64.getEncoder().encodeToString(json.getBytes("utf-8"));
            json = URLEncoder.encode(json, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        String resp = WMS_Request(json, "wms.order.add");

        Map<String, Object> resultMap = JSONObject.parseObject(resp, Map.class);
        String lgOrderNo = null == resultMap.get("otherSysOrderNo") ? "" : resultMap.get("otherSysOrderNo").toString();
        String code = String.valueOf(resultMap.get("code"));
        if (!"0".equals(code)) {
            log.info("===上传WMS失败，需要作登记处理==={}", request.getOrderNo());
            String messageText = String
                    .format(template, "跨境订单上传失败告警",
                            "supplychain-api", "order.upload_order_wms",
                            "500", "跨境订单异常_WMS",
                            "",
                            JSONObject.toJSONString("境外订单上传双子供应链WMS异常，子订单号：" + request.getOrderNo()));
            DingDingWebHookUtil.pushInfoToDingding(messageText, kuajing_accessToken);
            return false;
        }
        // 成功记录到mysql
        saveWmsOrderAddRecord(request.getOrderNo(), lgOrderNo, "WMS", AbroadOrderPushTypeEnum.ADD.getCode());
        return true;
    }

    private String WMS_Request(String json, String name) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 系统参数
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("name", name);
        param.put("app_key", wmsPlatformConfig.appKey);//wmsAppKey
        param.put("data", json);
        param.put("timestamp", sdf.format(new Date()));
        param.put("version", wmsPlatformConfig.version);
        try {
            String sign = WMSUtil.buildSign(param, wmsPlatformConfig.secret);//wmsSecret
            param.put("sign", sign);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String postJson = JSON.toJSONString(param);
        log.info("===wms推送请求参数：{}====", postJson);
        String resp = HttpClientUtil.doPostJson("https://open.gimicb.com/api", postJson);
        log.info("===处理上传WMS返回结果：{}=====", resp);
        return resp;
    }

    /**
     * LINK平台请求方法
     * @param json      数据体
     * @param method    方法名
     * @param code      资源code
     * @param secretKey 加密密钥
     * @return
     */
    public String LINK_Request(String json, String method, String code, String secretKey) {
        //正式环境
        String url = "http://link.cainiao.com/gateway/link.do";
        if (active.equals("dev") || active.equals("develop")) {
            //预发环境
            url = "https://prelink.cainiao.com/gateway/link.do";
        }
        String resp = HttpClientUtil.linkHttpUtil(url, method, code,
                LINKUtil.doSign(json, "utf-8", secretKey).replace("+", "%2B"),
                json);
        log.info("===link推送响应数据：{}===", resp);
        return resp;
    }

    public void queryAbroadOrderExpressInfo() {

    }

    /**
     * 保存发送记录
     * @param orderNo       子订单编号
     * @param serviceName   第三方服务名称
     * @param type          上传的类型 比如订单新增、售后订单
     */
    private void saveWmsOrderAddRecord(String orderNo, String lgOrderCode, String serviceName, Integer type) {
        log.info("===保存订单推送wms记录==={}, {}, {}", orderNo, serviceName, type);
        YxAbroadOrderRecord record = new YxAbroadOrderRecord();
        record.setOrderNo(orderNo);
        record.setServiceName(serviceName);
        record.setCreateTime(new Date());
        record.setType(type);
        record.setLgOrderCode(lgOrderCode);
        abroadOrderRecordMapper.insert(record);
    }

    /**
     * 获取wms 行政区域代码
     * @param province 省
     * @param city     市
     * @param area     区
     * @return
     */
    private static String getDistrict(String province, String city, String area) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Map<String, String> jsonMap = new HashMap<>();
        jsonMap.put("provinceName", province);
        jsonMap.put("cityName", city);
        jsonMap.put("districtName", area);

        String json = JSON.toJSONString(jsonMap);
        try {
            json = URLEncoder.encode(json, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // 系统参数
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("name", "base.data.district.get");
        param.put("app_key", "100012");//wmsAppKey
        param.put("data", json);
        param.put("timestamp", sdf.format(new Date()));
        param.put("version", "1.0");
        param.put("access_token", "");
        try {
            String sign = WMSUtil.buildSign(param, "8ddcff3a80f4189ca1c9d4d902c3c909");//wmsSecret
            param.put("sign", sign);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String postJson = JSON.toJSONString(param);
        log.info("===wms 查询行政区域代码：{}====", postJson);
        String resp = HttpClientUtil.doPostJson("https://open.gimicb.com/api", postJson);
        log.info("===wms 行政区域代码返回：{}=====", resp);
        Map<String, Object> resultMap = JSONObject.parseObject(resp, Map.class);
        String code = String.valueOf(resultMap.get("code"));
        if (!"0".equals(code)) {
            log.info("===上传WMS失败，需要作登记处理==={}");
        }
        Map<String, String> dataMap = JSONObject.parseObject(resultMap.get("data").toString(), Map.class);
        return dataMap.get("districtCode");
    }

    /**
     * @Description 异步保存订单数据到供应商
     */
    public void OrdersToBankerOrder(OrderUploadRequest request,YxOrders yxOrders) {

        log.info("查询到了一条订单详情id：{}", request.getChildOrderNo());
        if (null == request.getChildOrderNo()) {
            return;
        }
        Example example = new Example(YxBankerOrder.class);
        example.createCriteria().andEqualTo("childOrderNo", request.getChildOrderNo());
        List<YxBankerOrder> yxBankerOrders = bankerOrderMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(yxBankerOrders)) {
            log.info("该订单详情id已存在：{}", request.getChildOrderNo());
            return;
        }
        YxBankerProduct yxBankerProduct = bankerProductMapper.selectByPrimaryKey(request.getBankerProductId());
        YxBankerProductSpec yxBankerProductSpec = bankerProductSpecMapper.selectByPrimaryKey(request.getBankerProductSpecId());

        Example shopInfoExample = new Example(YxShopInfo.class);
        shopInfoExample.createCriteria().andEqualTo("shopId",yxOrders.getShopId());
        YxShopInfo yxShopInfo = shopInfoMapper.selectOneByExample(shopInfoExample);
        String orderNoPre = null !=yxShopInfo ? yxShopInfo.getShopId().substring(0,4) : "GUOB" ;

        log.info("==========供应商商品信息===============yxBankerProduct:{},yxBankerProductSpec:{}", yxBankerProduct, yxBankerProductSpec);

        log.info("==========开始同步订单信息到供应商===============");
        YxBankerOrder yxBankerOrder = new YxBankerOrder();
        yxBankerOrder.setOrderNo(orderNoPre + request.getOrderInfoId());
        yxBankerOrder.setChildOrderNo(request.getChildOrderNo());
        yxBankerOrder.setBankerId(request.getBankerId());
        yxBankerOrder.setUserName(request.getUserName());
        yxBankerOrder.setUserTel(request.getUserTel());
        String product = "";

//        try {
//            product = yxBankerProduct.getProductName() + "(" + yxBankerProductSpec.getSkuSpec() + ")";
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        yxBankerOrder.setProductName(StringUtils.isNotBlank(product) ? product : request.getProductName());
        yxBankerOrder.setProductPrice(request.getProductPrice());
        yxBankerOrder.setDeliveryAddress("");
        if (StringUtils.isNotEmpty(request.getDeliveryAddress())) {
            yxBankerOrder.setDeliveryAddress(request.getDeliveryAddress().replace("市辖区", ""));
        }
        yxBankerOrder.setCreateTime(request.getOrderDate());
        yxBankerOrder.setNote(request.getNote());
//        yxBankerOrder.setImportTime(new Date());
        yxBankerOrder.setIsExport((byte) 0);  // 未导出
        yxBankerOrder.setStatus((byte) 1);  // 无状态
        yxBankerOrder.setOrderStatus((byte) 0); // 未发货
        yxBankerOrder.setSource((byte) 2);   // 来源：新APP
        yxBankerOrder.setOrderInfoStatus(1);  //订单状态 待发货
        yxBankerOrder.setIsNewSync((byte) 0);
        yxBankerOrder.setSmallNote(request.getSmallNote());//订单小记
        yxBankerOrder.setThreeSkuId(request.getThreeSkuId());//外部sku-id
        if (null != yxBankerProductSpec && null != yxBankerProductSpec.getThreeSkuId()){
            yxBankerOrder.setThreeSkuId(yxBankerProductSpec.getThreeSkuId());//外部sku-id
        }
        yxBankerOrder.setProductSum(request.getProductSum());
        //省市区
        yxBankerOrder.setProvince(request.getProvince());
        yxBankerOrder.setCity(request.getCity());
        yxBankerOrder.setArea(request.getArea());
        yxBankerOrder.setIsZeroProduct(request.getIsZeroProduct());
        yxBankerOrder.setBankerProductId(request.getBankerProductId());
        yxBankerOrder.setPayType(request.getPayType());
        yxBankerOrder.setOrderSyncTime(new Date());
        log.info("===save banker order={}", yxBankerOrder);
        bankerOrderMapper.insertSelective(yxBankerOrder);

        try {
            //上传订单到聚水潭
            uploadOrderToJushuitan(request.getBankerId(),yxBankerProduct.getTypeno(),yxBankerOrder);
        } catch (Exception e) {
            log.error("===发送聚水潭失败==={}", e.getMessage());
        }

        try {
            //国外商品上传订单到菜鸟中心
            if (2 == yxBankerProduct.getIsExit()){
                uploadOrderToLink(yxOrders,yxBankerOrder,yxBankerProduct);
            }
        } catch (Exception e) {
            log.error("===上传订单到菜鸟中心失败==={}", e.getMessage());
        }
    }

    /**
     * 国外商品上传订单到菜鸟中心
     * @param orders
     * @param bankerOrder
     * @param bankerProduct
     */
    private void uploadOrderToLink(YxOrders orders,YxBankerOrder bankerOrder,YxBankerProduct bankerProduct) {
        if (!checkIsUploadToOtherSystem(bankerOrder.getChildOrderNo())) {
            return;
        }
        //验证该供应商是否需要上传菜鸟erp
        YxBanker banker = bankerMapper.selectByPrimaryKey(bankerOrder.getBankerId());
        if (null == banker.getErpId() || 1 == banker.getErpId()){
            return;
        }
        LinkErpResponse linkErp = linkErpService.getByBankId(bankerOrder.getBankerId());
        if (null == linkErp || 1 != linkErp.getStatus()){
            return;
        }
        Example example = new Example(CebOrder.class);
        example.createCriteria().andEqualTo("orderNo",orders.getChildOrderNo());
        example.setOrderByClause("id desc limit 1");
        CebOrder cebOrder = cebOrderMapper.selectOneByExample(example);
        if (null == cebOrder){
            return;
        }
        AbroadOrderDto dto = new AbroadOrderDto();
        dto.setExternalShopName(linkErp.getExternalShopName());
        dto.setOwnerUserId(linkErp.getOwnerUserId().toString());
        dto.setCode(linkErp.getCode());
        dto.setSecretKey(linkErp.getSecretKey());
        dto.setBusinessUnitId(linkErp.getBusinessUnitId());
        dto.setStoreCode(linkErp.getStoreCode());
        dto.setOrderSource(linkErp.getOrderSource());

        dto.setOrderNo(bankerOrder.getChildOrderNo());
        dto.setFreight(orders.getFreight());
        dto.setBuyerName(cebOrder.getBuyerName());
        dto.setBuyerRegNo(cebOrder.getBuyerRegNo());
        dto.setBuyerIdNumber(cebOrder.getBuyerIdNumber());
        dto.setPayTransactionId(cebOrder.getPayTransactionId());
        dto.setOrderTime(cebOrder.getOrderTime());
        dto.setTradingTime(cebOrder.getTradingTime());
        dto.setNote(cebOrder.getNote());
        dto.setOriginalPrice(bankerProduct.getOriginalPrice());
        dto.setTotalAmount(cebOrder.getTotalAmount());
        dto.setThreeSkuId(bankerOrder.getThreeSkuId());
        dto.setBankerProductId(bankerOrder.getBankerProductId());
        dto.setProductSum(bankerOrder.getProductSum());

        dto.setConsigneeAddress(cebOrder.getConsigneeAddress());
        dto.setProvince(bankerOrder.getProvince());
        dto.setCity(bankerOrder.getCity());
        dto.setArea(bankerOrder.getArea());

        dto.setLinkman(banker.getLinkman());
        //link系统上传
        handleToLINK(dto);
    }

    /**
     * 上传订单到聚水潭
     * @param bankerId
     * @param typeno
     * @param yxBankerOrder
     */
    private void uploadOrderToJushuitan(Integer bankerId,String typeno,YxBankerOrder yxBankerOrder){
        String[] jstBankerIds = jstBankerIdAll.split(",");
        if (!Arrays.asList(jstBankerIds).contains(bankerId.toString())) {
            log.info("===不需要发送聚水潭===", yxBankerOrder.getOrderNo());
            return;
        }
        log.info("===发送聚水潭开始==={}", yxBankerOrder.getOrderNo());
        String redisConstant = RedisConstants.OUT_ERP_KEY;
        String signShopId = stringRedisTemplate.opsForValue().get(redisConstant + "shopId:" + bankerId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        request.OrderUploadRequest uploadRequest = new request.OrderUploadRequest();
        uploadRequest.setShop_id(Integer.parseInt(signShopId));
        uploadRequest.setSo_id(yxBankerOrder.getOrderNo());
        uploadRequest.setOrder_date(sdf.format(yxBankerOrder.getCreateTime()));
        uploadRequest.setShop_status(JushuitanOrderStatusEnum.WAIT_SELLER_SEND_GOODS.getCode());
        uploadRequest.setShop_buyer_id(yxBankerOrder.getUserTel());
        uploadRequest.setReceiver_state(yxBankerOrder.getProvince());
        uploadRequest.setReceiver_city(yxBankerOrder.getCity());
        uploadRequest.setReceiver_district(yxBankerOrder.getArea());
        uploadRequest.setReceiver_address(yxBankerOrder.getDeliveryAddress());
        uploadRequest.setReceiver_name(yxBankerOrder.getUserName());
        uploadRequest.setReceiver_phone(yxBankerOrder.getUserTel());
        uploadRequest.setReceiver_mobile(yxBankerOrder.getUserTel());
        uploadRequest.setPay_amount(yxBankerOrder.getProductPrice());
        uploadRequest.setFreight(BigDecimal.ZERO);
        uploadRequest.setShop_modified(sdf.format(yxBankerOrder.getCreateTime()));

        OrderItemsRequest item = new OrderItemsRequest();
        item.setSku_id(null == yxBankerOrder.getThreeSkuId() ? "cessku-id" : yxBankerOrder.getThreeSkuId());
//        item.setShop_sku_id(String.valueOf(null == yxOrders.getProductSpecId() ? "cessku-id" : yxOrders.getProductSpecId()));
        item.setShop_sku_id(String.valueOf(StringUtils.isBlank(typeno) ? "cestypeno" : typeno));
        item.setAmount(yxBankerOrder.getProductPrice());
        item.setBase_price(yxBankerOrder.getProductPrice());
        item.setQty(yxBankerOrder.getProductSum());
        item.setName(yxBankerOrder.getProductName());
        item.setOuter_oi_id(String.valueOf(yxBankerOrder.getId()));
        List<OrderItemsRequest> items = new ArrayList<>();
        items.add(item);
        uploadRequest.setItems(items);

        OrderPayRequest payRequest = new OrderPayRequest();
        payRequest.setOuter_pay_id(String.valueOf(yxBankerOrder.getId()));
        payRequest.setPay_date(sdf.format(new Date()));
        payRequest.setPayment("在线支付");
        payRequest.setSeller_account(String.valueOf(yxBankerOrder.getBankerId()));
        payRequest.setBuyer_account(yxBankerOrder.getUserTel());
        payRequest.setAmount(yxBankerOrder.getProductPrice());
        uploadRequest.setPay(payRequest);

        List<request.OrderUploadRequest> sendJSTList = new ArrayList<>();
        sendJSTList.add(uploadRequest);
        sendJushuitan(String.valueOf(bankerId), sendJSTList);
    }

//    @Transactional
//    public void sendOrderToWDT(List<YxBankerOrder> yxBankerOrders) {
//        if (CollectionUtils.isEmpty(yxBankerOrders)) {
//            return;
//        }
//        String[] canUploadOrderBankerIds = wdtBankerId.split(",");
//        List<String> canUploadOrderBankerIdList = Arrays.asList(canUploadOrderBankerIds);
//        String redisConstant = RedisConstants.OUT_ERP_KEY;
//        yxBankerOrders.stream().forEach(yxBankerOrder -> {
//            //如果不是指定的供应商，则不需要上传订单
//            if (!canUploadOrderBankerIdList.contains(String.valueOf(yxBankerOrder.getBankerId()))) {
//                return;
//            }
//            String redisBankerOutErpSid = stringRedisTemplate.opsForValue().get(redisConstant + "sid:" + yxBankerOrder.getBankerId());
//            String redisBankerOutErpAppkey = stringRedisTemplate.opsForValue().get(redisConstant + "appkey:" + yxBankerOrder.getBankerId());
//            String redisBankerOutErpAppsecret = stringRedisTemplate.opsForValue().get(redisConstant + "appsecret:" + yxBankerOrder.getBankerId());
//            String redisBankerOutErpShopNo = stringRedisTemplate.opsForValue().get(redisConstant + "shopNo:" + yxBankerOrder.getBankerId());
//            if (StringUtils.isEmpty(redisBankerOutErpSid) || StringUtils.isEmpty(redisBankerOutErpAppkey)
//                    || StringUtils.isEmpty(redisBankerOutErpAppsecret) || StringUtils.isEmpty(redisBankerOutErpShopNo)) {
//                //todo 不存在的情况下需要知道从哪里取
//            }
//            YxOrdersInfo orderInfo = orderInfoDao.selectOrderInfoById(yxBankerOrder.getOrderInfoId());
//            YxOrders yxOrders = ordersDao.selectByPrimaryKey(orderInfo.getOrderId());
//            PushSelfResponse response = PushSelf.sendOrder(sid, appkey, appsecret, shopNo, wdtUrl, orderInfo, yxBankerOrder, yxOrders);
//            try {
//                log.info("===订单发送旺店通响应信息:{}", response);
//                List<request.OrderUploadLinkRequest> requests = new ArrayList<>();
//                request.OrderUploadLinkRequest request = new request.OrderUploadLinkRequest();
//                request.setSo_id(yxBankerOrder.getOrderNo());
//                requests.add(request);
//                if (response.getNewCount() <= 0) {
//                    log.info("===订单发送旺店通失败, 返回参数:{}", response);
//                    String rspMsg = "newCount=" + response.getNewCount() + ", changeCount=" + response.getChgCount();
//                    saveUploadOrderFailInfo(requests, 0, rspMsg);
//                    return;
//                }
//                saveUploadOrderFailInfo(requests, 1, null);
//                log.info("===订单发送旺店通成功===");
//            } catch (Exception e) {
//                log.error("===订单发送旺店通接口异常,{}", e);
//            }
//        });
//
//    }

    public YxOrders queryByChildOrderNo(String orderNo) {
        Example example = new Example(YxOrders.class);
        example.createCriteria().andEqualTo("childOrderNo", orderNo);
        List<YxOrders> ordersList = ordersMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(ordersList)) {
            return null;
        }
        return ordersList.get(0);
    }

    public YxOrders queryByChildOrderNoAndShopId(String orderNo, String shopId) {
        Example example = new Example(YxOrders.class);
        example.createCriteria().andEqualTo("childOrderNo", orderNo).andEqualTo("shopId", shopId);
        List<YxOrders> ordersList = ordersMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(ordersList)) {
            return null;
        }
        return ordersList.get(0);
    }

    public YxOrders queryByOrderInfoId(Integer orderInfoId) {
        Example example = new Example(YxOrders.class);
        example.createCriteria().andEqualTo("orderInfoId", orderInfoId);
        List<YxOrders> ordersList = ordersMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(ordersList)) {
            return null;
        }
        return ordersList.get(0);
    }

    public String getTypeno(String orderNo) {
        String typeno = bankerOrderMapper.getTypenoNew(Integer.valueOf(orderNo));
        return typeno;
    }

    private List<List<String>> getExcelHeadNew() {
        List<List<String>> head = new ArrayList<List<String>>();
        List<String> column0 = new ArrayList<String>();
        column0.add("订单ID");
        List<String> column1 = new ArrayList<String>();
        column1.add("订单号");
        List<String> column2 = new ArrayList<String>();
        column2.add("订单日期");
        List<String> column3 = new ArrayList<String>();
        column3.add("订单状态");
        List<String> column4 = new ArrayList<String>();
        column4.add("商品名称");
        List<String> column5 = new ArrayList<String>();
        column5.add("一级类目");
        List<String> column6 = new ArrayList<String>();
        column6.add("二级类目");
        List<String> column7 = new ArrayList<String>();
        column7.add("三级类目");
//        List<String> column8 = new ArrayList<String>();
//        column8.add("是否测评商品");
        List<String> column9 = new ArrayList<String>();
        column9.add("商品规格");
        List<String> column99 = new ArrayList<String>();
        column99.add("商品条码");
        List<String> column10 = new ArrayList<String>();
        column10.add("外部SKU");
        List<String> column11 = new ArrayList<String>();
        column11.add("商品数量");
        List<String> column12 = new ArrayList<String>();
        column12.add("商品款号");
        List<String> column13 = new ArrayList<String>();
        column13.add("商品总金额（成本+运费）");
        List<String> column14 = new ArrayList<String>();
        column14.add("商品成本");
        List<String> column15 = new ArrayList<String>();
        column15.add("商品运费");
        List<String> column16 = new ArrayList<String>();
        column16.add("订单备注");
        List<String> column17 = new ArrayList<String>();
        column17.add("客服备注");
        List<String> column18 = new ArrayList<String>();
        column18.add("发货时间");
        List<String> column19 = new ArrayList<String>();
        column19.add("快递公司");
        List<String> column20 = new ArrayList<String>();
        column20.add("快递单号");
        List<String> column21 = new ArrayList<String>();
        column21.add("收货人");
        List<String> column22 = new ArrayList<String>();
        column22.add("拆分快递（格式:京东物流:JD123456/顺丰速运:SF548248）");
        List<String> column23 = new ArrayList<String>();
        column23.add("手机号");
        List<String> column24 = new ArrayList<String>();
        column24.add("收货人所在省份");
        List<String> column25 = new ArrayList<String>();
        column25.add("收货人所在城市");
        List<String> column26 = new ArrayList<String>();
        column26.add("收货人所在区县");
        List<String> column27 = new ArrayList<String>();
        column27.add("收货人详细地址");
        List<String> column28 = new ArrayList<String>();
        column28.add("身份证姓名");
        List<String> column29 = new ArrayList<String>();
        column29.add("身份证号码");
        List<String> column30 = new ArrayList<String>();
        column30.add("售后状态");
        List<String> column31 = new ArrayList<String>();
        column31.add("售后单号");
        List<String> column32 = new ArrayList<>();
        column32.add("客服电话");
        List<String> column33 = new ArrayList<>();
        column33.add("签收时间");
//        List<String> column33 = new ArrayList<>();
//        column33.add("订单来源");
//        List<String> column31 = new ArrayList<String>();
//        column31.add("退款金额");

        head.add(column0);
        head.add(column1);
        head.add(column2);
        head.add(column3);
        head.add(column4);
        head.add(column5);
        head.add(column6);
        head.add(column7);
//        head.add(column8);
        head.add(column9);
        head.add(column99);
        head.add(column10);
        head.add(column11);
        head.add(column12);
        head.add(column13);
        head.add(column14);
        head.add(column15);
        head.add(column16);
        head.add(column17);
        head.add(column18);
        head.add(column19);
        head.add(column20);
        head.add(column21);
        head.add(column22);
        head.add(column23);
        head.add(column24);
        head.add(column25);
        head.add(column26);
        head.add(column27);
        head.add(column28);
        head.add(column29);
        head.add(column30);
        head.add(column31);
        head.add(column32);
        head.add(column33);
        return head;
    }

    private List<List<String>> getExcelHead() {
        List<List<String>> head = new ArrayList<List<String>>();
        List<String> column0 = new ArrayList<String>();
        column0.add("ID");
        List<String> column1 = new ArrayList<String>();
        column1.add("订单号");
        List<String> column2 = new ArrayList<String>();
        column2.add("姓名");
        List<String> column3 = new ArrayList<String>();
        column3.add("手机号");
        List<String> column4 = new ArrayList<String>();
        column4.add("时间");
        List<String> column5 = new ArrayList<String>();
        column5.add("产品");
        List<String> column6 = new ArrayList<>();
        column6.add("数量");
        List<String> column7 = new ArrayList<String>();
        column7.add("地址");
        List<String> column8 = new ArrayList<String>();
        column8.add("订单备注");
        List<String> column9 = new ArrayList<String>();
        column9.add("客服备注");
        List<String> column10 = new ArrayList<String>();
        column10.add("订单状态");
        List<String> column11 = new ArrayList<String>();
        column11.add("快递");
        List<String> column12 = new ArrayList<String>();
        column12.add("快递号");
        List<String> column13 = new ArrayList<>();
        column13.add("款号");
        List<String> column14 = new ArrayList<String>();
        column14.add("省");
        List<String> column15 = new ArrayList<String>();
        column15.add("市");
        List<String> column16 = new ArrayList<String>();
        column16.add("区");
        List<String> column17 = new ArrayList<String>();
        column17.add("外部SKU");


        head.add(column0);
        head.add(column1);
        head.add(column2);
        head.add(column3);
        head.add(column4);
        head.add(column5);
        head.add(column6);
        head.add(column7);
        head.add(column8);
        head.add(column9);
        head.add(column10);
        head.add(column11);
        head.add(column12);
        head.add(column13);
        head.add(column14);
        head.add(column15);
        head.add(column16);
        head.add(column17);
        return head;
    }

    public List<String> queryReturnGoodsListIn30Day(Integer bankerId) {
        LocalDateTime ldt = LocalDateTime.now(ZoneId.systemDefault());
        ldt = ldt.plusDays(-60);
        Date date = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
        Example example = new Example(YxBankerOrder.class);
        example.createCriteria().andEqualTo("bankerId", bankerId)
                .andGreaterThanOrEqualTo("createTime", date)
                .andIn("orderInfoStatus", Arrays.asList(3, 4, 5, 6));
        example.selectProperties("childOrderNo");
        List<YxBankerOrder> ordersList = bankerOrderMapper.selectByExample(example);
        List<String> result = ordersList.stream().map(YxBankerOrder::getChildOrderNo).collect(Collectors.toList());
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateOrdersExpressInfo(List<OrdersExpressRequest> ordersExpressRequestList) {
        YxBanker userInfo = bankerService.getUserInfo();
        if (CollectionUtils.isEmpty(ordersExpressRequestList)) {
            log.info("===没有需要导入的数据===");
            return;
        }

        List<BankerOrderExpressRequest> list = ordersExpressRequestList.stream()
                .map(item -> {
                    BankerOrderExpressRequest request = new BankerOrderExpressRequest();
                    BeanUtils.copyProperties(item, request);
                    request.setUpdateTime(new Date());
                    request.setExpressCode(ExpressDicUtil.getValue(item.getExpressCode().trim()));
                    request.setExpressName(item.getExpressCode().trim());
                    return request;
                }).collect(Collectors.toList());
        List<OrdersExpressRequest> list2 = ordersExpressRequestList.stream()
                .map(item -> {
                    OrdersExpressRequest request = new OrdersExpressRequest();
                    BeanUtils.copyProperties(item, request);
                    request.setUpdateTime(new Date());
                    request.setExpressCode(ExpressDicUtil.getValue(item.getExpressCode().trim()));
                    return request;
                }).collect(Collectors.toList());
        try {
            log.info("导入快递信息：{}", JSONObject.toJSONString(list));
            // 更新供应商订单快递
//            AtomicBoolean b = new AtomicBoolean(true);
            List<String> childOrderNoList = new ArrayList<>();
            list.stream().forEach(item -> {
                item.setExpressNo(item.getExpressNo().trim());
                try {
                    deleteImportBeforeExpressInfo(item.getChildOrderNo(), item.getExpressCode(), item.getExpressNo());
                } catch (Exception e) {
                    log.error("===删除旧订单数据异常==={}", e);
                }
                int result = bankerOrderMapper.updateBankerOrdersBySingle(item);
                //如果存在异常单改为已处理
                YxOrderException yxOrderException = orderExceptionMapper.selectByPrimaryKey(item.getOrderNo());
                if (null != yxOrderException) {
                    YxOrderException newOrderException = new YxOrderException();
                    newOrderException.setId(yxOrderException.getId());
                    newOrderException.setStatus(new Byte("2"));
                    newOrderException.setHandlePerson(userInfo.getId().toString());
                    newOrderException.setHandleTime(new Date());
                    newOrderException.setExpressCode(item.getExpressCode());
                    newOrderException.setExpressNo(item.getExpressNo());
                    orderExceptionMapper.updateByPrimaryKeySelective(newOrderException);
                    //记录备注
                    YxOrderExceptionNote yxOrderExceptionNote = new YxOrderExceptionNote();
                    yxOrderExceptionNote.setCreateTime(new Date());
                    yxOrderExceptionNote.setContent("【已处理】已导入快递单号-系统自动修改成已处理");
                    yxOrderExceptionNote.setOrderExceptionId(yxOrderException.getId());
                    yxOrderExceptionNote.setAdminName(userInfo.getId().toString());
                    orderExceptionNoteMapper.insertSelective(yxOrderExceptionNote);
                }
                if(result > 0) {
                    childOrderNoList.add(item.getChildOrderNo());
                }

                log.info("拆分快递信息:expressRecord{}",item.getExpressRecordStr());
                expressRecordsMapper.updateInvalidFlag(item.getChildOrderNo());
                String[] array = StringUtils.isNotBlank(item.getExpressRecordStr()) ?  item.getExpressRecordStr().split("/") : null;
                if (array != null && array.length != 0) {
                    List<String> expressRecord = Arrays.asList(array);
                    expressRecord.forEach(a ->{
                        String[] expressRecordStr = a.split(":");
                        YxExpressRecords records = new YxExpressRecords();
                        records.setCompanyNo(ExpressDicUtil.getMapValue(expressRecordStr[0]));
                        records.setExpressEno(expressRecordStr[1]);
                        records.setChildOrderNo(item.getChildOrderNo());
                        records.setCreateTime(new Date());
                        records.setInvalidFlag(0);
                        expressRecordsMapper.insertSelective(records);

                    });
                }
                YxOrders yxOrders = queryByChildOrderNo(item.getChildOrderNo());
                syncOrderExpress(item.getChildOrderNo(),item.getExpressCode(),item.getExpressNo(),0,yxOrders.getShopId(),new Date(),item.getExpressName());
            });
            if (!CollectionUtils.isEmpty(childOrderNoList)){
                ordersMapper.updateOrdersByChildOrderNos(childOrderNoList);
            }

            // todo 这里不更新发货时间了，到时候直接查供应商订单表的导入时间

            log.info("===========供应商导入快递信息成功========== size:{}", list.size());
        } catch (Exception e) {
            log.info(" 失败异常信息 :{}", GlobalExceptionHandler.getExceptionToString(e));
            throw new ApiException("导入失败，请核对表格重试！");
        }

    }

    /**
     * 同步更新销售端订单物流信息及订单状态
     */
    public void syncOrderExpress(String childOrderNo,String expressCode,String expressNo,Integer updateOrderFlag,String shopId,Date importTime,String expressName) {
        try{
            OrderExpressBack request = new OrderExpressBack();
            request.setChildOrderNo(childOrderNo);
            request.setExpressCode(expressCode);
            request.setExpressNo(expressNo);
            request.setOrderInfoStatus(2);
            request.setImportTime(importTime);
            request.setUpdateOrderFlag(updateOrderFlag);
            request.setExpressName(expressName);
            log.info("======同步更新销售端订单物流信息及订单状态====参数==={}", request);
            if (shopId.equals("GUOB004") || shopId.equals("GUOB005")|| shopId.equals("GUOB006")) {
                guchuangRabbitTemplate.convertAndSend(QueueConstants.QUERY_SYNC_ORDER_EXPRESS, JSONObject.toJSONString(request, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue));
            }
//            else if (shopId.equals("JUMD005") || shopId.equals("JUMD006") || shopId.equals("JUMD007")) {
//                jumaiduoRabbitTemplate.convertAndSend(QueueConstants.QUERY_SYNC_ORDER_EXPRESS, JSONObject.toJSONString(request, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue));
//            } else if(shopId.equals("YQKJ006") || shopId.equals("YQKJ007") || shopId.equals("YQKJ008")) {
//                yiquanRabbitTemplate.convertAndSend(QueueConstants.QUERY_SYNC_ORDER_EXPRESS, JSONObject.toJSONString(request, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue));
//            } else if(shopId.equals("ZXLP005") || shopId.equals("ZXLP006") || shopId.equals("ZXLP007")) {
//                zxlpRabbitTemplate.convertAndSend(QueueConstants.QUERY_SYNC_ORDER_EXPRESS, JSONObject.toJSONString(request, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue));
//            } else if(shopId.equals("YGYX005") || shopId.equals("YGYX006") || shopId.equals("YGYX007") || shopId.equals("YGYX008")) {
//                ygyxRabbitTemplate.convertAndSend(QueueConstants.QUERY_SYNC_ORDER_EXPRESS, JSONObject.toJSONString(request, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue));
//            } else if(shopId.equals("YXHD005") || shopId.equals("YXHD006") || shopId.equals("YXHD007") || shopId.equals("YXHD008")) {
//                yxhdRabbitTemplate.convertAndSend(QueueConstants.QUERY_SYNC_ORDER_EXPRESS, JSONObject.toJSONString(request, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue));
//            } else if(shopId.equals("JCYX005") || shopId.equals("JCYX006") || shopId.equals("JCYX007") || shopId.equals("JCYX008")) {
//                jckjRabbitTemplate.convertAndSend(QueueConstants.QUERY_SYNC_ORDER_EXPRESS, JSONObject.toJSONString(request, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue));
//            }
        }catch (Exception e) {
            log.error(" 同步更新销售端订单物流信息及订单状态失败异常信息 :{}", GlobalExceptionHandler.getExceptionToString(e));
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public void updateOrdersExpressInfoBySupplyChain(List<SupplyChainImportOrdersExpressRequest> ordersExpressRequestList) {
        if (CollectionUtils.isEmpty(ordersExpressRequestList)) {
            log.info("===没有需要导入的数据===");
            return;
        }
        List<BankerOrderExpressRequest> list = ordersExpressRequestList.stream()
                .map(item -> {
                    BankerOrderExpressRequest request = new BankerOrderExpressRequest();
                    BeanUtils.copyProperties(item, request);
                    request.setUpdateTime(new Date());
                    request.setExpressCode(ExpressDicUtil.getValue(item.getExpressCode().trim()));
                    return request;
                }).collect(Collectors.toList());
        List<OrdersExpressRequest> list2 = ordersExpressRequestList.stream()
                .map(item -> {
                    OrdersExpressRequest request = new OrdersExpressRequest();
                    BeanUtils.copyProperties(item, request);
                    request.setUpdateTime(new Date());
                    request.setExpressCode(ExpressDicUtil.getValue(item.getExpressCode().trim()));
                    return request;
                }).collect(Collectors.toList());
        try {
            log.info("导入快递信息：{}", JSONObject.toJSONString(list));
            // 更新供应商订单快递
            AtomicBoolean b = new AtomicBoolean(true);
            list.stream().forEach(item -> {
                item.setExpressNo(item.getExpressNo().trim());
                try {
                    deleteImportBeforeExpressInfo(item.getChildOrderNo(), item.getExpressCode(), item.getExpressNo());
                } catch (Exception e) {
                    log.error("===删除旧订单数据异常==={}", e);
                }
                int result = bankerOrderMapper.updateBankerOrdersBySingle(item);
                if (result <= 0) {
                    b.set(false);
                }
                log.info("拆分快递信息:expressRecord{}",item.getExpressRecordStr());
                expressRecordsMapper.updateInvalidFlag(item.getChildOrderNo());
                String[] array = StringUtils.isNotBlank(item.getExpressRecordStr()) ?  item.getExpressRecordStr().split("/") : null;
                if (array != null && array.length != 0) {
                    List<String> expressRecord = Arrays.asList(array);
                    expressRecord.forEach(a ->{
                        String[] expressRecordStr = a.split(":");
                        YxExpressRecords records = new YxExpressRecords();
                        records.setCompanyNo(ExpressDicUtil.getMapValue(expressRecordStr[0]));
                        records.setExpressEno(expressRecordStr[1]);
                        records.setChildOrderNo(item.getChildOrderNo());
                        records.setCreateTime(new Date());
                        records.setInvalidFlag(0);
                        expressRecordsMapper.insertSelective(records);

                    });
                }
            });
            if (b.get()) {
                ordersMapper.updateOrders(list2);
            }
            // todo 这里不更新发货时间了，到时候直接查供应商订单表的导入时间
            log.info("===========供应商导入快递信息成功========== size:{}", list.size());
        } catch (Exception e) {
            log.info(" 失败异常信息 :{}", GlobalExceptionHandler.getExceptionToString(e));
            throw new ApiException("导入失败，请核对表格重试！");
        }
    }

    /**
     * 再次导入时，如果有更新，则需要清理express_orders和exception_order表数据
     * @param childOrderNo
     */
    private void deleteImportBeforeExpressInfo(String childOrderNo, String newExpressCode, String newExpressNo) {
        if (StringUtils.isBlank(childOrderNo)) {
            return;
        }
        Example example = new Example(YxBankerOrder.class);
        example.createCriteria().andEqualTo("childOrderNo", childOrderNo);
        example.orderBy("id").desc();
        List<YxBankerOrder> bankerOrders = bankerOrderMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(bankerOrders)) {
            return;
        }
        YxBankerOrder bankerOrder = bankerOrders.get(0);
        if (StringUtils.isEmpty(bankerOrder.getExpressCode()) && StringUtils.isEmpty(bankerOrder.getExpressNo())) {
            return;
        }

        if (!newExpressCode.equals(bankerOrder.getExpressCode()) || !newExpressNo.equals(bankerOrder.getExpressNo())) {
            //查询yx_express_orders表数据
            Example expressExample = new Example(YxExpressOrders.class);
            expressExample.createCriteria().andEqualTo("companyNo", bankerOrder.getExpressCode())
                    .andEqualTo("expressEno", bankerOrder.getExpressNo());
            List<YxExpressOrders> expressOrdersList = expressOrdersMapper.selectByExample(expressExample);
            if (CollectionUtils.isEmpty(expressOrdersList)) {
                return;
            }
            //清除yx_express_orders表数据
            expressOrdersList.stream().forEach(item -> {
                expressOrdersMapper.delete(item);
            });

            Example exceptionExample = new Example(YxOrderException.class);
            exceptionExample.createCriteria().andEqualTo("expressNo", bankerOrder.getExpressNo())
                    .andEqualTo("expressCode", bankerOrder.getExpressCode());
            List<YxOrderException> orderExceptionList = orderExceptionMapper.selectByExample(exceptionExample);
            if (CollectionUtils.isEmpty(orderExceptionList)) {
                return;
            }
            //清除yx_order_exception表数据
            orderExceptionList.stream().forEach(item -> {
                orderExceptionMapper.delete(item);
            });
        }


    }

    public boolean insertExpressOrder(YxExpressOrders request) {
        // 快递是否存已存在
        Example expressOrderExample = new Example(YxExpressOrders.class);
        expressOrderExample.createCriteria().andEqualTo("companyNo", request.getCompanyNo()).andEqualTo("expressEno", request.getExpressEno());
        List<YxExpressOrders> expressOrders = expressOrdersMapper.selectByExample(expressOrderExample);
        if(CollectionUtils.isEmpty(expressOrders)){
            expressOrdersMapper.insertSelective(request);
        }
        return true;
    }

    public boolean updateOrderInfo(UpdateOrderInfoRequest request) {
        if (CollectionUtils.isEmpty(request.getChildOrderNoList()) && null == request.getOrderStatus()) {
            YxOrders yxOrders = new YxOrders();
            yxOrders.setUserName(request.getUserName());
            yxOrders.setUserTel(request.getUserTel());
            yxOrders.setDeliveryAddress(request.getDeliveryAddress());
            yxOrders.setNote(request.getNote());
            Example example = new Example(YxOrders.class);
            example.createCriteria().andEqualTo("childOrderNo", request.getChildOrderNo());
            ordersMapper.updateByExampleSelective(yxOrders, example);

            Example example1 = new Example(YxBankerOrder.class);
            example1.createCriteria().andEqualTo("childOrderNo", request.getChildOrderNo());
            List<YxBankerOrder> yxBankerOrders = bankerOrderMapper.selectByExample(example1);
            if (!CollectionUtils.isEmpty(yxBankerOrders)) {
                YxBankerOrder yxBankerOrder = yxBankerOrders.get(0);
                yxBankerOrder.setUserName(request.getUserName());
                yxBankerOrder.setUserTel(request.getUserTel());
                yxBankerOrder.setDeliveryAddress(request.getDeliveryAddress());
                yxBankerOrder.setNote(request.getNote());
                bankerOrderMapper.updateByPrimaryKeySelective(yxBankerOrder);
            }
        } else if (!CollectionUtils.isEmpty(request.getChildOrderNoList()) && null == request.getOrderStatus()) {
            //修改导出信息
            bankerOrderMapper.updateIsExportByChildOrderNoList(request.getChildOrderNoList());
        } else if (!CollectionUtils.isEmpty(request.getChildOrderNoList()) && null != request.getOrderStatus()) {
            if (request.getOrderStatus() == 6){
                ordersMapper.updateOrderStatus(request.getChildOrderNoList().get(0), 6);
                bankerOrderMapper.updateOrderInfoStatus(request.getChildOrderNoList().get(0), 6);
            }else {
                //恢复订单状态
                ordersMapper.updateOrderStatus(request.getChildOrderNoList().get(0), request.getOrderStatus());
                bankerOrderMapper.updateOrderInfoStatus(request.getChildOrderNoList().get(0), request.getOrderStatus());
                returnGoodsMapper.updateStatusByServiceNo(request.getServiceNo(), 7,request.getServiceDesc());
            }
        }
        return false;
    }

    public CommonResult updateOrderReceiveStatus(String childOrderNo) {
        Example example = new Example(YxOrders.class);
        example.createCriteria().andEqualTo("childOrderNo", childOrderNo);
        List<YxOrders> yxOrdersList = ordersMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(yxOrdersList)) {
            return CommonResult.failed();
        }
        YxOrders yxOrders = yxOrdersList.get(0);
        if (null == yxOrders.getReceiveStatus() && yxOrders.getOrderStatus() != 6 ) {
            yxOrders.setOrderStatus(Integer.valueOf(OrderStatusEnums.FINISH.getStatus()));
            yxOrders.setReceiveStatus(1);
            yxOrders.setReceiveTime(new Date());
            ordersMapper.updateByPrimaryKeySelective(yxOrders);
            //同步修改供应商订单状态
            bankerOrderMapper.updateOrderInfoStatus(childOrderNo, Integer.valueOf(OrderStatusEnums.FINISH.getStatus()));
        }
        return CommonResult.success();
    }

    @Transactional
    public void updateOrderStatus(String childOrderNo, Integer status) {
        ordersMapper.updateOrderStatus(childOrderNo, status);
        bankerOrderMapper.updateOrderInfoStatus(childOrderNo, status);
    }

    public void updateOrderStatusByRpc(String shopId, String childOrderNo, Integer status) {
        if (OrdersStatusEnum.CLOSE.getCode().equals(status)){
            ordersMapper.updateOrderStatusByShopId1(shopId, childOrderNo);
        }else {
            ordersMapper.updateOrderStatusByShopId(shopId, childOrderNo, status);
        }
        bankerOrderMapper.updateOrderInfoStatus(childOrderNo, status);
    }

    public List<String> selectByChildOrderNo(List<String> childOrderNo) {
        if (CollectionUtils.isEmpty(childOrderNo)){
            return new ArrayList<>();
        }
        List<String> childOrderNoList = new ArrayList<>();
        if (childOrderNo.size() >= 20) {
            int num = childOrderNo.size() / 20;
            int more = childOrderNo.size() % 20;
            if (more > 0) {
                num = num + 1;
            }
            for (int i = 0; i < num - 1; i++) {
                childOrderNoList.addAll(ordersMapper.selectChildOrderNoByChildOrderNoList(childOrderNo.subList(i * 20, i * 20 + 20)));
            }
            childOrderNoList.addAll(ordersMapper.selectChildOrderNoByChildOrderNoList(childOrderNo.subList((num - 1) * 20, childOrderNo.size())));
        } else {
            childOrderNoList = ordersMapper.selectChildOrderNoByChildOrderNoList(childOrderNo);
        }
//        Example example = new Example(YxOrders.class);
//        example.createCriteria().andIn("childOrderNo", childOrderNo);
//        List<YxOrders> yxOrdersList = ordersMapper.selectByExample(example);
//        List<String> collect = yxOrdersList.stream().map(YxOrders::getChildOrderNo).collect(Collectors.toList());
        //如果一个都查不到,直接返回
        if (CollectionUtils.isEmpty(childOrderNoList)){
            return childOrderNo;
        }
        List<String> finalChildOrderNoList = childOrderNoList;
        List<String> collect = childOrderNo.stream().filter(item -> !finalChildOrderNoList.contains(item)).collect(Collectors.toList());
        return collect;
    }

    public Map<String, String> checkLogistics(String expressCompanyNo, String expressNo) {
        // 快递记录
        Example example = new Example(YxExpressOrders.class);
        example.createCriteria()
                .andEqualTo("expressEno", expressNo);
        example.setOrderByClause("create_time desc");
        List<YxExpressOrders> expressOrders = expressOrdersMapper.selectByExample(example);

        // 配送公司记录
        Example expressDicExample = new Example(YxExpressDic.class);
        expressDicExample.createCriteria().andEqualTo("expressValue", expressCompanyNo);
        expressDicExample.setOrderByClause("id desc");
        List<YxExpressDic> expressDics = expressDicMapper.selectByExample(expressDicExample);

        Map<String, String> map = new HashMap<>();
        if(expressDics.size() > 0){
            YxExpressDic yxExpressDic = expressDics.get(0);
            map.put("expressKey", yxExpressDic.getExpressKey());
            map.put("expressEno", expressNo);
        }
        if (expressOrders.size() > 0 ) {
            YxExpressOrders yxExpressOrders = expressOrders.get(0);
            map.put("infoText", yxExpressOrders.getInfoText());
            map.put("status", String.valueOf(yxExpressOrders.getStatus()));
        }
        return map;
    }

    public void pullOrderToJuishuitanSystem(String orderNo) {
        Example example = new Example(YxBankerOrder.class);
        example.createCriteria().andEqualTo("orderNo", orderNo);
        example.orderBy("id").desc();
        YxBankerOrder yxBankerOrder = bankerOrderMapper.selectOneByExample(example);
        if (null == yxBankerOrder) {
            return;
        }
        Example example2 = new Example(YxOrders.class);
        example2.createCriteria().andEqualTo("childOrderNo", yxBankerOrder.getChildOrderNo());
        example2.orderBy("id").desc();
        YxOrders yxOrders = ordersMapper.selectOneByExample(example2);

        Example example3 = new Example(YxBankerProduct.class);
        example3.createCriteria().andEqualTo("id", yxBankerOrder.getBankerProductId());
        YxBankerProduct yxBankerProduct = bankerProductMapper.selectOneByExample(example3);

        String redisConstant = RedisConstants.OUT_ERP_KEY;
        String signShopId = stringRedisTemplate.opsForValue().get(redisConstant + "shopId:" + yxBankerOrder.getBankerId());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


        request.OrderUploadRequest uploadRequest = new request.OrderUploadRequest();
        uploadRequest.setShop_id(Integer.parseInt(signShopId));
        uploadRequest.setSo_id(yxBankerOrder.getOrderNo());
        uploadRequest.setOrder_date(sdf.format(yxBankerOrder.getCreateTime()));
        uploadRequest.setShop_status(JushuitanOrderStatusEnum.WAIT_SELLER_SEND_GOODS.getCode());
        uploadRequest.setShop_buyer_id(yxBankerOrder.getUserTel());
        uploadRequest.setReceiver_state(yxBankerOrder.getProvince());
        uploadRequest.setReceiver_city(yxBankerOrder.getCity());
        uploadRequest.setReceiver_district(yxBankerOrder.getArea());
        uploadRequest.setReceiver_address(yxBankerOrder.getDeliveryAddress());
        uploadRequest.setReceiver_name(yxBankerOrder.getUserName());
        uploadRequest.setReceiver_phone(yxBankerOrder.getUserTel());
        uploadRequest.setReceiver_mobile(yxBankerOrder.getUserTel());
        uploadRequest.setPay_amount(yxBankerOrder.getProductPrice());
        uploadRequest.setFreight(BigDecimal.ZERO);
        uploadRequest.setShop_modified(sdf.format(yxBankerOrder.getCreateTime()));
        OrderPayRequest payRequest = new OrderPayRequest();
        payRequest.setOuter_pay_id(String.valueOf(yxOrders.getId()));
        payRequest.setPay_date(sdf.format(null == yxOrders.getPayDate() ? new Date() : yxOrders.getPayDate()));
        payRequest.setPayment("在线支付");
        payRequest.setSeller_account(String.valueOf(yxBankerOrder.getBankerId()));
        payRequest.setBuyer_account(yxBankerOrder.getUserTel());
        payRequest.setAmount(yxBankerOrder.getProductPrice());
        uploadRequest.setPay(payRequest);

        OrderItemsRequest item = new OrderItemsRequest();
        item.setSku_id(null == yxBankerOrder.getThreeSkuId() ? "cessku-id" : yxBankerOrder.getThreeSkuId());
//        item.setShop_sku_id(String.valueOf(null == yxOrders.getProductSpecId() ? "cessku-id" : yxOrders.getProductSpecId()));
        item.setShop_sku_id(String.valueOf(null == yxBankerProduct.getTypeno() ? "cestypeno" : yxBankerProduct.getTypeno()));
        item.setAmount(yxBankerOrder.getProductPrice());
        item.setBase_price(yxBankerOrder.getProductPrice());
        item.setQty(yxBankerOrder.getProductSum());
        item.setName(yxBankerOrder.getProductName());
        item.setOuter_oi_id(String.valueOf(yxOrders.getId()));
        List<OrderItemsRequest> items = new ArrayList<>();
        items.add(item);
        uploadRequest.setItems(items);

        List<request.OrderUploadRequest> sendJSTList = new ArrayList<>();
        sendJSTList.add(uploadRequest);
        sendJushuitan(String.valueOf(yxBankerOrder.getBankerId()), sendJSTList);
        log.info("===补单到聚水潭成功===");
    }

    /**
     * 团购上传订单
     * @param requestList
     * @return
     */
    public Integer uploadByGroup(List<OrderUploadRequest> requestList) {
        log.info("===========团购上传订单==========参数requestList::{}", JSONObject.toJSONString(requestList));
        AtomicReference<Integer> count = new AtomicReference<>(0);
        requestList.stream().forEach(request -> {
            log.info("===========上传供应链订单==========childOrderNo::{}", request.getChildOrderNo());
            RLock lock = redissonClient.getLock("ORDER_UPLOAD" + request.getChildOrderNo());
            boolean b = false;
            try {
                b = lock.tryLock(0, 5, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                lock.unlock();
            }
            if (!b) {
                log.info("正在上传供应链，{}",request.getChildOrderNo());
                throw new ApiException("正在上传供应链" + request.getChildOrderNo());
            }
            Example example = new Example(YxOrders.class);
            example.createCriteria().andEqualTo("childOrderNo", request.getChildOrderNo());
            List<YxOrders> yxOrdersList = ordersMapper.selectByExample(example);
            if (!CollectionUtils.isEmpty(yxOrdersList)) {
                return;
            }
            if (!CollectionUtils.isEmpty(request.getOrdersPayDTOList())){
                List<OrdersPayDTO> ordersPayDTOList = request.getOrdersPayDTOList();
                ordersPayDTOList.stream().forEach(ordersPayDTO ->{
                    log.info("===========上传供应链团购订单==========ordersPayDTO::{}", JSONObject.toJSONString(ordersPayDTO));
                    Example ordersPayExample = new Example(YxOrdersPay.class);
                    ordersPayExample.createCriteria().andEqualTo("orderNo", ordersPayDTO.getOrderNo());
                    List<YxOrdersPay> yxOrdersPayList = ordersPayMapper.selectByExample(ordersPayExample);
                    if (CollectionUtils.isEmpty(yxOrdersPayList)) {
                        YxOrdersPay yxOrdersPay = new YxOrdersPay();
                        BeanUtils.copyProperties(ordersPayDTO,yxOrdersPay);
                        if (StringUtils.isNotBlank(yxOrdersPay.getResText())){
                            try {
                                Map map = JSONObject.parseObject(yxOrdersPay.getResText(), Map.class);
                                String transactionId = (String) map.get("transactionId");
                                yxOrdersPay.setResText(transactionId);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        yxOrdersPay.setChildOrderNo(request.getChildOrderNo());
                        ordersPayMapper.insertSelective(yxOrdersPay);
                    }
                });
            }
            //供应链商品
            YxProduct yxProduct = productMapper.selectByPrimaryKey(request.getProductId());
            request.setBankerProductId(yxProduct.getBankerProductId());
            request.setBankerId(yxProduct.getBankerId());
            List<YxOrdersSpec> ordersSpecNumList = new ArrayList<>();
            //供应链多规格
            final BigDecimal[] supplyPrice = {BigDecimal.ZERO};
            final BigDecimal[] costPrice = {BigDecimal.ZERO};
            AtomicReference<String> skuSpec = new AtomicReference<>("");
            if (!CollectionUtils.isEmpty(request.getYxOrdersSpecList())){
                List<OrdersSpecDTO> yxOrdersSpecList = request.getYxOrdersSpecList();
                yxOrdersSpecList.stream().forEach(ordersSpecDTO -> {
                    YxOrdersSpec yxOrdersSpec = new YxOrdersSpec();
                    BeanUtils.copyProperties(ordersSpecDTO,yxOrdersSpec);
                    orderSpecMapper.insertSelective(yxOrdersSpec);
                    ordersSpecNumList.add(yxOrdersSpec);
                    YxProductSpec yxProductSpec = productSpecMapper.selectByPrimaryKey(ordersSpecDTO.getSpecId());
                    //商品规格名称
                    skuSpec.set(skuSpec + "   " + yxProductSpec.getSkuSpec() + "×" + ordersSpecDTO.getSpecNum() + "件");
                    //供货价
                    supplyPrice[0] = supplyPrice[0].add(yxProductSpec.getSupplyPrice().multiply(new BigDecimal(ordersSpecDTO.getSpecNum())));

                    costPrice[0] = costPrice[0].add(yxProductSpec.getCostPrice().multiply(new BigDecimal(yxOrdersSpec.getSpecNum())));
                });
            }
            YxOrders yxOrders = new YxOrders();
            BeanUtils.copyProperties(request, yxOrders);
            yxOrders.setProductName(yxProduct.getProductName() + "(" + skuSpec.get() + ")");
            yxOrders.setOrderStatus(1);
            //总供货价
            yxOrders.setProductPrice(supplyPrice[0]);
//            //总成本价
            yxOrders.setCostPrice(costPrice[0]);
            //计算集采价格
            try {
                yxOrders = calculationProductSumGreaterOne(yxOrders, yxProduct.getBankerProductId(), ordersSpecNumList);
            } catch (Exception e) {
                log.info("===团购订单计算集采价异常==={}{}", yxOrders.getChildOrderNo(), e);
            }
            //计算运费
            YxBankerProduct yxBankerProduct = bankerProductMapper.selectByPrimaryKey(request.getBankerProductId());
            if (null!=yxBankerProduct.getFreightId()){
                yxOrders.setFreight(calculateFreight(yxBankerProduct.getFreightId(),request.getProductSum(),request.getCity(),request.getProvince()));
            }else {
                yxOrders.setFreight(new BigDecimal(0));
            }
//            //计算运费
//            yxOrders.setFreight(calculateFreight(request.getFreightId(),request.getProductSum(),request.getCity(),request.getProvince()));
            int insert = ordersMapper.insert(yxOrders);
            //保存到供应商订单表
            request.setProductPrice(yxOrders.getCostPrice());
            request.setProductName(yxOrders.getProductName());
            request.setBankerProductId(yxProduct.getBankerProductId());
            GroupOrdersToBankerOrder(request);
            count.set(count.get() + insert);
            if (null != lock) {
                lock.unlock();
            }
        });
        return count.get();
    }

    public void GroupOrdersToBankerOrder(OrderUploadRequest request) {

        log.info("查询到了一条订单详情id：{}", request.getChildOrderNo());
        if (null == request.getChildOrderNo()) {
            return;
        }
        Example example = new Example(YxBankerOrder.class);
        example.createCriteria().andEqualTo("childOrderNo", request.getChildOrderNo());
        List<YxBankerOrder> yxBankerOrders = bankerOrderMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(yxBankerOrders)) {
            log.info("该订单详情id已存在：{}", request.getChildOrderNo());
            return;
        }
        YxBankerProduct yxBankerProduct = bankerProductMapper.selectByPrimaryKey(request.getBankerProductId());
//        YxBankerProductSpec yxBankerProductSpec = bankerProductSpecMapper.selectByPrimaryKey(request.getBankerProductSpecId());

        log.info("==========供应商商品信息===============yxBankerProduct:{},yxBankerProductSpec:{}", yxBankerProduct, request.getYxOrdersSpecList());

        log.info("==========开始同步订单信息到供应商===============");
        YxBankerOrder yxBankerOrder = new YxBankerOrder();
        yxBankerOrder.setOrderNo("QMYX" + request.getOrderInfoId());
        yxBankerOrder.setChildOrderNo(request.getChildOrderNo());
        yxBankerOrder.setBankerId(request.getBankerId());
        yxBankerOrder.setUserName(request.getUserName());
        yxBankerOrder.setUserTel(request.getUserTel());
        String product = "";

        yxBankerOrder.setProductName(StringUtils.isNotBlank(product) ? product : request.getProductName());
        yxBankerOrder.setProductPrice(request.getProductPrice());
        yxBankerOrder.setDeliveryAddress("");
        if (StringUtils.isNotEmpty(request.getDeliveryAddress())) {
            yxBankerOrder.setDeliveryAddress(request.getDeliveryAddress().replace("市辖区", ""));
        }
        yxBankerOrder.setCreateTime(request.getOrderDate());
        yxBankerOrder.setNote(request.getNote());
//        yxBankerOrder.setImportTime(new Date());
        yxBankerOrder.setIsExport((byte) 0);  // 未导出
        yxBankerOrder.setStatus((byte) 1);  // 无状态
        yxBankerOrder.setOrderStatus((byte) 0); // 未发货
        yxBankerOrder.setSource((byte) 2);   // 来源：新APP
        yxBankerOrder.setOrderInfoStatus(1);  //订单状态 待发货
        yxBankerOrder.setIsNewSync((byte) 0);
        yxBankerOrder.setSmallNote(request.getSmallNote());//订单小记
        yxBankerOrder.setThreeSkuId(request.getThreeSkuId());//外部sku-id
        // todo 外部sku-id 多规格外部sku-id有多个 该怎么处理???
//        if (null != yxBankerProductSpec && null != yxBankerProductSpec.getThreeSkuId()){
//            yxBankerOrder.setThreeSkuId(yxBankerProductSpec.getThreeSkuId());//外部sku-id
//        }
        yxBankerOrder.setProductSum(request.getProductSum());
        //省市区
        yxBankerOrder.setProvince(request.getProvince());
        yxBankerOrder.setCity(request.getCity());
        yxBankerOrder.setArea(request.getArea());
        yxBankerOrder.setIsZeroProduct(request.getIsZeroProduct());
        yxBankerOrder.setBankerProductId(request.getBankerProductId());

        log.info("===save banker order={}", yxBankerOrder);
        bankerOrderMapper.insertSelective(yxBankerOrder);

        try {
            //上传订单到聚水潭
            groupOrderToJushuitan(yxBankerOrder,request,yxBankerProduct);
        } catch (Exception e) {
            log.error("===发送聚水潭失败==={}", e);
        }
    }

    /**
     * 团购订单上传聚水潭
     * @param yxBankerOrder
     * @param request
     * @param yxBankerProduct
     */
    private void groupOrderToJushuitan(YxBankerOrder yxBankerOrder,OrderUploadRequest request,YxBankerProduct yxBankerProduct){
        String[] jstBankerIds = jstBankerIdAll.split(",");
        if (!Arrays.asList(jstBankerIds).contains(request.getBankerId().toString())) {
            log.info("===不需要发送聚水潭===", yxBankerOrder.getOrderNo());
            return;
        }
        log.info("===发送聚水潭开始==={}", yxBankerOrder.getOrderNo());
        String redisConstant = RedisConstants.OUT_ERP_KEY;
        String signShopId = stringRedisTemplate.opsForValue().get(redisConstant + "shopId:" + request.getBankerId());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        request.OrderUploadRequest uploadRequest = new request.OrderUploadRequest();
        uploadRequest.setShop_id(Integer.parseInt(signShopId));
        uploadRequest.setSo_id(yxBankerOrder.getOrderNo());
        uploadRequest.setOrder_date(sdf.format(yxBankerOrder.getCreateTime()));
        uploadRequest.setShop_status(JushuitanOrderStatusEnum.WAIT_SELLER_SEND_GOODS.getCode());
        uploadRequest.setShop_buyer_id(yxBankerOrder.getUserTel());
        uploadRequest.setReceiver_state(yxBankerOrder.getProvince());
        uploadRequest.setReceiver_city(yxBankerOrder.getCity());
        uploadRequest.setReceiver_district(yxBankerOrder.getArea());
        uploadRequest.setReceiver_address(yxBankerOrder.getDeliveryAddress());
        uploadRequest.setReceiver_name(yxBankerOrder.getUserName());
        uploadRequest.setReceiver_phone(yxBankerOrder.getUserTel());
        uploadRequest.setReceiver_mobile(yxBankerOrder.getUserTel());
        uploadRequest.setPay_amount(yxBankerOrder.getProductPrice());
        uploadRequest.setFreight(BigDecimal.ZERO);
        uploadRequest.setShop_modified(sdf.format(yxBankerOrder.getCreateTime()));

        List<OrderItemsRequest> items = new ArrayList<>();
        List<OrdersSpecDTO> yxOrdersSpecList = request.getYxOrdersSpecList();
        if (!CollectionUtils.isEmpty(yxOrdersSpecList)) {
            yxOrdersSpecList.stream().forEach(item -> {
                String threeSkuId = "";

                Example productSpecExample = new Example(YxProductSpec.class);
                productSpecExample.createCriteria().andEqualTo("id", item.getSpecId());
                YxProductSpec productSpec = productSpecMapper.selectOneByExample(productSpecExample);
                if (null != productSpec) {
                    Example bankerProductSpecExample = new Example(YxBankerProductSpec.class);
                    bankerProductSpecExample.createCriteria().andEqualTo("id", productSpec.getSupplyId());
                    YxBankerProductSpec bankerProductSpec = bankerProductSpecMapper.selectOneByExample(bankerProductSpecExample);
                    threeSkuId = bankerProductSpec.getThreeSkuId();
                }

                OrderItemsRequest orderItem = new OrderItemsRequest();
                orderItem.setSku_id(StringUtils.isEmpty(threeSkuId) ? "cessku-id" : threeSkuId);
                orderItem.setShop_sku_id(String.valueOf(null == yxBankerProduct.getTypeno() ? "cestypeno" : yxBankerProduct.getTypeno()));
                orderItem.setAmount(yxBankerOrder.getProductPrice());
                orderItem.setBase_price(yxBankerOrder.getProductPrice());
                orderItem.setQty(item.getSpecNum());
                orderItem.setName(yxBankerOrder.getProductName());
                orderItem.setOuter_oi_id(String.valueOf(yxBankerOrder.getId()));
                items.add(orderItem);
            });
        }
        uploadRequest.setItems(items);

        OrderPayRequest payRequest = new OrderPayRequest();
        payRequest.setOuter_pay_id(String.valueOf(yxBankerOrder.getId()));
        payRequest.setPay_date(sdf.format(new Date()));
        payRequest.setPayment("在线支付");
        payRequest.setSeller_account(String.valueOf(yxBankerOrder.getBankerId()));
        payRequest.setBuyer_account(yxBankerOrder.getUserTel());
        payRequest.setAmount(yxBankerOrder.getProductPrice());
        uploadRequest.setPay(payRequest);

        List<request.OrderUploadRequest> sendJSTList = new ArrayList<>();
        sendJSTList.add(uploadRequest);
        sendJushuitan(String.valueOf(request.getBankerId()), sendJSTList);
    }

    /**
     * 订阅快递信息
     * @param expressNo   快递单号
     * @param expressCode 快递公司
     * @return  0-订阅失败 1-订阅成功
     */
    public Integer subscribeExpress(String expressNo, String expressCode,String userTel) {
        if (!kuaidi100_subscrib_switch.equals(1)) {
            log.info("===订阅开关未开启===");
            return 0;
        }
        if (StringUtils.isEmpty(expressNo) || StringUtils.isEmpty(expressCode)) {
            log.info("===快递单号或快递公司为空==={}，{}", expressNo, expressCode);
            return 0;
        }
        //订阅次数累加1
        Integer integer = expressOrdersMapper.updateSubscribeStatusByExpress(expressCode, expressNo,"add");
        if (integer <= 0) {
            return 0;
        }
        SubscribeParameters subscribeParameters = new SubscribeParameters();
        subscribeParameters.setCallbackurl(kuaidi100_url);
        subscribeParameters.setResultv2("4");
        subscribeParameters.setPhone(StringUtils.deleteWhitespace(userTel));
        SubscribeParam subscribeParam = new SubscribeParam();
        subscribeParam.setParameters(subscribeParameters);
        subscribeParam.setCompany(StringUtils.deleteWhitespace(expressCode.toLowerCase()));
        subscribeParam.setNumber(StringUtils.deleteWhitespace(expressNo));
        subscribeParam.setKey(kuaidi100_key);
        SubscribeNewReq subscribeReq = new SubscribeNewReq();
        subscribeReq.setSchema(ApiInfoConstant.SUBSCRIBE_SCHEMA);
        subscribeReq.setParam(new Gson().toJson(subscribeParam));
        log.info("===订阅快递100请求参数:{}=====", JSONObject.toJSONString(subscribeReq));
        IBaseClient subscribe = new Subscribe();
        try {
            HttpResult result = subscribe.execute(subscribeReq);
            log.info("===订阅快递100响应结果:{}=====", JSONObject.toJSONString(result));
            if (null != result && result.getStatus() == 200) {
                JSONObject jsonObject = JSON.parseObject(result.getBody());
                String returnCode = jsonObject.get("returnCode").toString();
                if ("200".equals(returnCode)) {
                    return 1;
                } else {
                    if (Arrays.asList("600", "601").contains(returnCode)) {
                        FeiShuUtil.sendMsg("快递100账号无可用单量，需要充值！");
                    }
                    //订阅失败,订阅次数减1
                    expressOrdersMapper.updateSubscribeStatusByExpress(expressCode, expressNo,"sub");
                    return 0;
                }
            }
        } catch (Exception e) {
            log.error(String.format("===调用快递100订阅接口出错===s%, s%", expressCode, expressNo), e);
        }
        return 0;
    }

    public CommonResult updateAddress(ReceiveAddressRequest request) {
        Integer count = 0;
        //修改bankerOrder收货地址
        Example bankerOrderExample = new Example(YxBankerOrder.class);
        bankerOrderExample.createCriteria().andEqualTo("childOrderNo",request.getChildOrderNo());
        List<YxBankerOrder> yxBankerOrders = bankerOrderMapper.selectByExample(bankerOrderExample);
        if (!CollectionUtils.isEmpty(yxBankerOrders)){
            log.info("============修改bankerOrder收货地址==========查询到的订单{}",JSONObject.toJSONString(yxBankerOrders));
            YxBankerOrder yxBankerOrder = yxBankerOrders.get(0);
            yxBankerOrder.setProvince(request.getProvince());
            yxBankerOrder.setCity(request.getCity());
            yxBankerOrder.setArea(request.getArea());
            yxBankerOrder.setUserName(request.getUserName());
            yxBankerOrder.setUserTel(request.getUserPhone());
            yxBankerOrder.setDeliveryAddress(request.getProvince() + StringUtils.defaultIfBlank(request.getCity(),"")
                    + StringUtils.defaultIfBlank(request.getArea(),"")
                    + StringUtils.defaultIfBlank(request.getAddress(),""));
            count = bankerOrderMapper.updateByPrimaryKey(yxBankerOrder);
        }
        //修改order收货地址
        Example orderExample = new Example(YxOrders.class);
        orderExample.createCriteria().andEqualTo("childOrderNo",request.getChildOrderNo());
        List<YxOrders> yxOrdersList = ordersMapper.selectByExample(orderExample);
        if (!CollectionUtils.isEmpty(yxOrdersList)){
            log.info("============修改order收货地址==========查询到的订单{}",JSONObject.toJSONString(yxOrdersList));
            YxOrders yxOrders = yxOrdersList.get(0);
            yxOrders.setUserName(request.getUserName());
            yxOrders.setUserTel(request.getUserPhone());
            yxOrders.setDeliveryAddress(request.getProvince() + StringUtils.defaultIfBlank(request.getCity(),"")
                    + StringUtils.defaultIfBlank(request.getArea(),"")
                    + StringUtils.defaultIfBlank(request.getAddress(),""));
            count = ordersMapper.updateByPrimaryKey(yxOrders);
        }
        log.info("============修改收货地址=========={}",count);
        if (count > 0){
            return CommonResult.success();
        }
       return CommonResult.failed();
    }

    public ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(10,
            50,
            5,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(1024 * 1024));

    public Map<String, Object> uploadAttachInfo(OrderUploadAttachInfoRequest request, YxShopInfo shopInfo) {
        Map<String, Object> result = new HashMap();
        //成功数
        AtomicInteger successNum = new AtomicInteger(0);
        //成功订单编号集合
        List<String> successOrderNoList = Collections.synchronizedList(new ArrayList<>());
        //失败订单编号集合
        List<String> failOrderNoList = Collections.synchronizedList(new ArrayList<>());

        CountDownLatch downLatch = new CountDownLatch(request.getData().size());
        request.getData().stream().forEach(item -> {
            poolExecutor.submit(() -> {
                try {
                    CebOrderResponse oldOrder = cebOrderMapper.findByOrderNo(item.getChildOrderNo());
                    if (null != oldOrder) {
                        failOrderNoList.add(item.getChildOrderNo());
                        return;
                    }
                    //组装ceb_order数据
                    CebOrder cebOrder = generaterCebOrder(item);
                    int num = cebOrderMapper.insertSelective(cebOrder);
                    if (num <= 0) {
                        failOrderNoList.add(item.getChildOrderNo());
                        return;
                    }

                    item.getItem().stream().forEach(goods -> {
                        //组装ceb_order_goodsinfo数据
                        CebOrderGoodsinfo orderGoodsinfo = generateCebOrderGoodsinfo(goods, cebOrder.getId());
                        cebOrderGoodsinfoMapper.insertSelective(orderGoodsinfo);
                    });
                    successNum.incrementAndGet();
                    successOrderNoList.add(item.getChildOrderNo());
                } catch (Exception e) {
                    failOrderNoList.add(item.getChildOrderNo());
                    log.info("===报关订单附加信息保存异常==={}", item.getChildOrderNo());
                    log.error("===保存报关订单附加信息异常==={}", e);
                    String messageText = String
                            .format(template, "跨境报关订单信息异常",
                                    "supplychain-api", "order.upload_attach_info",
                                    "500", "跨境报关订单信息异常",
                                    "",
                                    JSONObject.toJSONString("报关订单附加信息保存异常，子订单号：" + item.getChildOrderNo()));
                    DingDingWebHookUtil.pushInfoToDingding(messageText, kuajing_accessToken);
                } finally {
                    downLatch.countDown();
                }
            });

        });
        try {
            downLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        result.put("successNum", successNum.get());
        result.put("successOrderNoList", successOrderNoList);
        result.put("failOrderNoList", failOrderNoList);
        return result;
    }

    /**
     * 组装ceb_order数据
     * @param item
     * @return
     */
    private CebOrder generaterCebOrder(OrderAttachInfoRequest item) {
//        AtomicInteger index = new AtomicInteger(1);
//        IdWorker idWorker = new IdWorker(1,1,index.get());
        CebOrder cebOrder = new CebOrder();
        cebOrder.setGuid(UUID.randomUUID().toString().replaceAll("-", ""));
        cebOrder.setOrderNo(item.getChildOrderNo());
        cebOrder.setBuyerRegNo(item.getBuyerRegNo());
        cebOrder.setBuyerName(item.getBuyerName());
        cebOrder.setBuyerTelephone(item.getBuyerTelephone());
        cebOrder.setBuyerIdType(item.getBuyerIdType());
        cebOrder.setBuyerIdNumber(item.getBuyerIdNumber());
        cebOrder.setPayCode(item.getPayCode());
        cebOrder.setPayName(item.getPayName());
        cebOrder.setPayTransactionId(item.getPayTransactionId());
        cebOrder.setConsignee(item.getConsignee());
        cebOrder.setConsigneeTelephone(item.getConsigneeTelephone());
        cebOrder.setConsigneeAddress(item.getConsigneeAddress());
        cebOrder.setNote(item.getNote());
        cebOrder.setOrderTime(item.getOrderTime());
        cebOrder.setCreateTime(item.getCreateTime());
        cebOrder.setVerDept(item.getVerDept());
        cebOrder.setTotalAmount(item.getTotalAmount());
        cebOrder.setSendStatus(CebOrderSendStatusEnums.UN_SEND.getStatus());
        cebOrder.setShopId(item.getShopId());
        cebOrder.setPayType(item.getPayType());
        cebOrder.setTradingTime(item.getTradingTime());
        cebOrder.setRecpAccount(item.getRecpAccount());
        cebOrder.setRecpName(item.getRecpName());
        cebOrder.setRecpCode(item.getRecpCode());
        cebOrder.setInitalRequest(item.getInitalRequest());
        cebOrder.setInitalResponse(item.getInitalResponse());
        return cebOrder;
    }

    /**
     * 组装ceb_order_goodsinfo数据
     * @param goods
     * @param cebOrderId
     * @return
     */
    private CebOrderGoodsinfo generateCebOrderGoodsinfo(OrderItemAttachInfoRequest goods, int cebOrderId) {
        YxProduct yxProduct = productMapper.selectByPrimaryKey(goods.getSupplyProductId());//供应链商品id
        YxProductSpec yxProductSpec = productSpecMapper.selectByPrimaryKey(goods.getSupplyProductSpecId());//供应链商品规格id
        YxBankerProductSpec yxBankerProductSpec = bankerProductSpecMapper.selectByPrimaryKey(yxProductSpec.getSupplyId());
        YxBankerProduct bankerProduct = bankerProductMapper.selectByPrimaryKey(yxProduct.getBankerProductId());

        CebOrderGoodsinfo orderGoodsinfo = new CebOrderGoodsinfo();
        orderGoodsinfo.setOrderId(cebOrderId);
        orderGoodsinfo.setItemNo(String.valueOf(goods.getSupplyProductSpecId()));
        orderGoodsinfo.setItemName(goods.getItemName());
        orderGoodsinfo.setGmodel(yxProduct.getProductName() + "(" + yxProductSpec.getSkuSpec() + ")");
        orderGoodsinfo.setItemDescribe(goods.getItemDescribe());
        orderGoodsinfo.setBarCode(yxBankerProductSpec.getGoodsCode());
        orderGoodsinfo.setUnit(String.valueOf(bankerProduct.getUnitCode()));
        orderGoodsinfo.setCountry(bankerProduct.getCountryCode());
        orderGoodsinfo.setQty(goods.getQty());
        orderGoodsinfo.setPrice(goods.getPrice());
        orderGoodsinfo.setTotalPrice(goods.getPrice().multiply(new BigDecimal(goods.getQty())));
        orderGoodsinfo.setCurrency("142");
        orderGoodsinfo.setItemLink(goods.getItemLink());
        return orderGoodsinfo;
    }

    /**
     * 查询wms系统跨境订单清单回执信息
     * 测试的时候需要wms那边设置2个边界状态（成功完成状态和失败状态），用来判断我们这边不需要再去获取第三方系统信息
     */
    public void selectAbroadOrderReceipt() {
        List<String> orderNoList = ordersMapper.selectWaitCEB622MessageList();
        if (CollectionUtils.isEmpty(orderNoList)) {
            return;
        }
        orderNoList.stream().forEach(orderNo -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("messageType", "CEB622Message");
            jsonObject.put("sn", orderNo);
            jsonObject.put("returnType", "1");
            jsonObject.put("merchantId", "100012");
            String resp = null;
            try {
                String json = URLEncoder.encode(jsonObject.toJSONString(), "utf-8");
                resp = WMS_Request(json, "crms.receipt.get");
            } catch (UnsupportedEncodingException e) {
                log.info("===wms回执查询异常{}", e);
                return;
            }

            Map<String, Object> resultMap = JSONObject.parseObject(resp, Map.class);
            String code = String.valueOf(resultMap.get("code"));
            if (!"0".equals(code)) {
                log.info("===WMS回执查询失败==={}, {}", orderNo);
                return;
            }
            updateCebOrderData(orderNo, resultMap.get("code").toString());
        });
    }

    /**
     * 更新ceb_order表 清单回执状态等信息
     * @param orderNo   子订单编号
     * @param code      wms返回清单信息
     */
    private void updateCebOrderData(String orderNo, String code) {
        List<Map<String, Object>> xmlMaps = parseXml(code);
        if (CollectionUtils.isEmpty(xmlMaps)) {
            return;
        }
        List<Map<String, Object>> matchList = xmlMaps.stream().filter(map -> orderNo.equals(map.get("preNo"))).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(matchList)) {
            return;
        }
        Map<String, Object> map = matchList.get(0);
        String returnStatus = String.valueOf(map.get("returnStatus"));
        String returnTime = String.valueOf(map.get("returnTime"));
        String returnInfo = String.valueOf(map.get("returnInfo"));
        cebOrderMapper.updateCebOrder622Data(orderNo, returnStatus, returnTime, returnInfo);
    }

    /**
     * 解析xml
     * @param data xml格式字符串
     * @return
     */
    private List<Map<String, Object>> parseXml(String data) {
        List<Map<String, Object>> treeMapList = new ArrayList<>();
        try {
            Document doc = DocumentHelper.parseText(data);
            Element roots = doc.getRootElement();
            Iterator elements=roots.elementIterator();
            while (elements.hasNext()){
                Map<String,Object> mapData = new HashMap();
                Element child= (Element) elements.next();
//                System.out.println("节点名称 = [" + child.getName() + "]"+"节点内容："+child.getText());
                List subElemets=child.elements();
                //System.out.println(subElemets.size());
                for(int i=0;i<subElemets.size();i++){
                    Element subChild= (Element) subElemets.get(i);
                    mapData.put(subChild.getName(),subChild.getText());
                    //System.out.println("子节点名称："+subChild.getName()+";子节点内容："+subChild.getText());
                }
                treeMapList.add(mapData);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return treeMapList;
    }

    public CommonResult updateFreight(String startTime, String endTime,String childOrderNo) {
        Example example = new Example(YxBankerOrder.class);
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)){
            example.createCriteria().andLessThanOrEqualTo("createTime",endTime).andGreaterThanOrEqualTo("createTime",startTime);
        }
        if (StringUtils.isNotBlank(childOrderNo)){
            example.createCriteria().andEqualTo("childOrderNo",childOrderNo);
        }
        example.selectProperties("childOrderNo","bankerProductId","province","city","productSum");
        List<YxBankerOrder> yxBankerOrders = bankerOrderMapper.selectByExample(example);
        log.info("=============查询到的订单数量================{}",yxBankerOrders.size());
        List<Integer> bankerProductIds = yxBankerOrders.stream().map(YxBankerOrder::getBankerProductId).distinct().collect(Collectors.toList());
        List<YxBankerProduct> bankerProducts = new ArrayList<>();
        if (!CollectionUtils.isEmpty(bankerProductIds)) {
            if (bankerProductIds.size() >= 20) {
                int num = bankerProductIds.size() / 20;
                int more = bankerProductIds.size() % 20;
                if (more > 0) {
                    num = num + 1;
                }
                for (int i = 0; i < num - 1; i++) {
                    bankerProducts.addAll(bankerProductMapper.selectFreightIdById(bankerProductIds.subList(i * 20, i * 20 + 20)));
                }
                bankerProducts.addAll(bankerProductMapper.selectFreightIdById(bankerProductIds.subList((num - 1) * 20, bankerProductIds.size())));
            } else {
                bankerProducts = bankerProductMapper.selectFreightIdById(bankerProductIds);
            }
        }
//        AtomicReference<Integer> count = new AtomicReference<>(0);
        AtomicInteger count = new AtomicInteger();
        List<YxBankerProduct> finalBankerProducts = bankerProducts;
        yxBankerOrders.forEach(bankerOrder ->{
            log.info("=============bankerOrder================{}",bankerOrder);
            List<YxBankerProduct> bankerProductList = finalBankerProducts.stream().filter(item -> bankerOrder.getBankerProductId().equals(item.getId())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(bankerProductList)){
                return;
            }
            YxBankerProduct bankerProduct = bankerProductList.get(0);
            log.info("=============bankerProduct================{}",bankerProduct);
            if (null!=bankerProduct.getFreightId()){
                BigDecimal freight = calculateFreight(bankerProduct.getFreightId(), bankerOrder.getProductSum(), bankerOrder.getCity(), bankerOrder.getProvince());
                log.info("=============bankerProduct================{}",bankerProduct);
                ordersMapper.updateFreightByChildOrderNo(bankerOrder.getChildOrderNo(),freight);
                count.getAndIncrement();
            }else {
                ordersMapper.updateFreightByChildOrderNo(bankerOrder.getChildOrderNo(),BigDecimal.ZERO);
                count.getAndIncrement();
            }
        });
        return CommonResult.success(count.get());
    }



    /**
     * 组装订单完成的参数到kafka
     * @param childOrderNo 子订单号
     * @param status
     * @return
     */
    public OrderToKafkaDTO packParamToKafkaByCompletedOrder(String childOrderNo,Integer status, Date completedTime, Date closeTime){
        Example recordExample = new Example(YxOrderKafkaRecord.class);
        recordExample.createCriteria().andEqualTo("childOrderNo",childOrderNo).andEqualTo("status",status);
        if (orderKafkaRecordMapper.selectCountByExample(recordExample) > 0){
            return null;
        }

        Example example = new Example(YxOrders.class);
        example.createCriteria().andEqualTo("childOrderNo",childOrderNo);
        example.setOrderByClause("id desc limit 1");
        YxOrders yxOrders = ordersMapper.selectOneByExample(example);

        Example banExample = new Example(YxBankerOrder.class);
        banExample.createCriteria().andEqualTo("childOrderNo",childOrderNo);
        banExample.setOrderByClause("id desc limit 1");
        YxBankerOrder yxBankerOrder = bankerOrderMapper.selectOneByExample(banExample);

        Example dutyExample = new Example(ReturnDuty.class);
        dutyExample.createCriteria().andEqualTo("childOrderNo",childOrderNo);
        dutyExample.setOrderByClause("id desc limit 1");
        List<ReturnDuty> returnDuties = returnDutyMapper.selectByExample(dutyExample);


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String substring = childOrderNo.substring(0, 1);
        String project = "";
        switch (substring){
            case "MZ":
                project = "淘心购";
                break;
            case "Q":
                project = "xxxx";
                break;
            default:
                break;
        }
//
//        String orderStatus = "";
//        switch (status){
//            case 3:
//                orderStatus = "已完成";
//                break;
//            case 4:
//                orderStatus = "已关闭";
//                break;
//            default:
//                break;
//        }

        OrderToKafkaDTO dto = OrderToKafkaDTO.builder()
                .childOrderNo(childOrderNo)
                .bankerId(yxBankerOrder.getBankerId())
                .orderDate(sdf.format(yxBankerOrder.getCreateTime()))
                .project(project)
                .orderStatus(status)
                .completedTime(status.equals(3) ? sdf.format(completedTime) : null)
                .closeTime(status.equals(4) ? sdf.format(closeTime) : null)
                .productImg(yxOrders.getProductImg())
                .productName(yxOrders.getProductName())
                .skuSpec(yxOrders.getProductSkuSpec())
                .productId(yxOrders.getProductId())
                .skuId(yxOrders.getProductSpecId())
                .costPrice(yxBankerOrder.getProductPrice())
                .productNum(yxOrders.getProductSum())
                .freight(yxOrders.getFreight())
                .freightDuty(!CollectionUtils.isEmpty(returnDuties) ? returnDuties.get(0).getFreightDuty() : null)
                .freightDutyFee(!CollectionUtils.isEmpty(returnDuties) ? returnDuties.get(0).getFreightDutyFee() : null)
                .returnDuty(!CollectionUtils.isEmpty(returnDuties) ? returnDuties.get(0).getReturnDuty() : null)
                .returnDutyFee(!CollectionUtils.isEmpty(returnDuties) ? returnDuties.get(0).getReturnDutyFee() : null)
                .build();

        //记录数据到db
        YxOrderKafkaRecord yxOrderKafkaRecord = new YxOrderKafkaRecord();
        BeanUtils.copyProperties(dto,yxOrderKafkaRecord);
        yxOrderKafkaRecord.setStatus(status);
        yxOrderKafkaRecord.setBillStatus(1);
        orderKafkaRecordMapper.insertSelective(yxOrderKafkaRecord);
        String dtoStr = JSONObject.toJSONString(dto);
        Map<String,String> map = new HashMap<>();
        map.put("msgStr",dtoStr);
        HttpClientUtil.doGet(callBack_host + "/sendMsgToSalesPlace",map);
        return dto;
    }

    @Autowired(required = false)
    private KafkaSendService kafkaSendService;

    @Value("${spring.profiles.active:dev}")
    private String profile;

    /**
     * 获取订单数据并发到kafka
     * @param childOrderNos
     * @return
     */
    public void getOrderMsg(List<String> childOrderNos) {
        List<YxBankerOrder> yxBankerOrder = bankerOrderMapper.selectByChildOrderNo(childOrderNos);
        AtomicReference<String> msg = new AtomicReference<>("");
        if (!CollectionUtils.isEmpty(yxBankerOrder)){
            yxBankerOrder.stream().forEach(item ->{
                msg.set(JSONObject.toJSONString(item, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue));
                //发送到kafka
                try{
                    boolean sendStatus = isSendStatus(msg.get());
                    log.info("sendOrderMsgToKafkaStatus={}",sendStatus);
                }catch (Exception e){
                    log.error("发送到kafka错误",e);
                }
            });
        }
        List<YxOrders> yxOrders = ordersMapper.selectByChildOrderNo(childOrderNos);
        if (!CollectionUtils.isEmpty(yxOrders)){
            yxOrders.stream().forEach(item ->{
                msg.set(JSONObject.toJSONString(item, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue));
                //发送到kafka
                try{
                    boolean sendStatus = isSendStatus(msg.get());
                    log.info("sendOrderMsgToKafkaStatus={}",sendStatus);
                }catch (Exception e){
                    log.error("发送到kafka错误",e);
                }
            });
        }
        List<ReturnDuty> returnDuty = returnDutyMapper.selectByChildOrderNo(childOrderNos);
        if (!CollectionUtils.isEmpty(returnDuty)){
            returnDuty.stream().forEach(item ->{
                msg.set(JSONObject.toJSONString(item, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue));
                //发送到kafka
                try{
                    boolean sendStatus = isSendStatus(msg.get());
                    log.info("sendOrderMsgToKafkaStatus={}",sendStatus);
                }catch (Exception e){
                    log.error("发送到kafka错误",e);
                }
            });
        }
    }

    private boolean isSendStatus(String msg) {
        if ("pd".equals(profile)){
            return kafkaSendService.middleEndTrade(msg);
        }else {
            return kafkaSendService.middleEndTradeTest(msg);
        }

    }

    @Resource
    private OrderSendKafkaRecordMapper orderSendKafkaRecordMapper;

    /**
     * 检查完成的和关闭的订单，并发送到kafka
     */
    public void checkOrderToKafkaRecord() {
        List<String> childOrderNos = new ArrayList<>();
        //查看今天之前已完成的订单
        List<OrderToKafkaRecordDTO> completeOrders = ordersMapper.selectOrdersToKafka(3);
        if (!CollectionUtils.isEmpty(completeOrders)){
            childOrderNos.addAll(completeOrders.stream().map(OrderToKafkaRecordDTO::getChildOrderNo).collect(Collectors.toList()));
            //在记录表存在的订单
            List<String> existList = completeOrders.stream().filter(e -> StringUtils.isNotBlank(e.getNoExist())).map(OrderToKafkaRecordDTO::getChildOrderNo).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(existList)){
                orderSendKafkaRecordMapper.updateBatch(existList,1,0);
            }
            //在记录表中不存在的订单
            List<String> noExistList = completeOrders.stream().filter(e -> !StringUtils.isNotBlank(e.getNoExist())).map(OrderToKafkaRecordDTO::getChildOrderNo).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(noExistList)){
                orderSendKafkaRecordMapper.insertBatch(noExistList,1,0);
            }
        }
        //查看今天之前已关闭的订单
        List<OrderToKafkaRecordDTO> closeOrders = ordersMapper.selectOrdersToKafka(4);
        if (!CollectionUtils.isEmpty(closeOrders)){
            childOrderNos.addAll(closeOrders.stream().map(OrderToKafkaRecordDTO::getChildOrderNo).collect(Collectors.toList()));
            //在记录表存在的订单
            List<String> existList = closeOrders.stream().filter(e -> StringUtils.isNotBlank(e.getNoExist())).map(OrderToKafkaRecordDTO::getChildOrderNo).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(existList)){
                orderSendKafkaRecordMapper.updateBatch(existList,1,1);
            }
            //在记录表中不存在的订单
            List<String> noExistList = closeOrders.stream().filter(e -> !StringUtils.isNotBlank(e.getNoExist())).map(OrderToKafkaRecordDTO::getChildOrderNo).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(noExistList)){
                orderSendKafkaRecordMapper.insertBatch(noExistList,1,1);
            }
        }
        //发送kafka
        if (!CollectionUtils.isEmpty(childOrderNos)){
//            getOrderMsg(childOrderNos);
        }
    }

    /**
     * 更新为已完成
     * @param yxOrder 符合条件的订单
     * @return void
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderFinished(YxOrders yxOrder) {
        ordersMapper.updateOrderFinishState(yxOrder.getId(), 1);
        Example bankerOrderExample = new Example(YxBankerOrder.class);
        bankerOrderExample.createCriteria().andEqualTo("childOrderNo", yxOrder.getChildOrderNo());
        List<YxBankerOrder> yxBankerOrders = bankerOrderMapper.selectByExample(bankerOrderExample);
        if (!CollectionUtils.isEmpty(yxBankerOrders)) {
            bankerOrderMapper.updateOrderInfoFinishState(yxBankerOrders.get(0).getId(), 1);
        }
        log.info("====订单：{} 已更新为已完成====", yxOrder.getChildOrderNo());
    }

    /**
     * 更新为未完成
     * @param yxOrder 符合条件的订单
     * @return void
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderUnFinished(YxOrders yxOrder) {
        log.info("====开始更新订单为已发货：" + yxOrder.getChildOrderNo());
        ordersMapper.updateOrderFinishState(yxOrder.getId(), 0);
        Example bankerOrderExample = new Example(YxBankerOrder.class);
        bankerOrderExample.createCriteria().andEqualTo("childOrderNo", yxOrder.getChildOrderNo());
        List<YxBankerOrder> yxBankerOrders = bankerOrderMapper.selectByExample(bankerOrderExample);
        if (!CollectionUtils.isEmpty(yxBankerOrders)) {
            bankerOrderMapper.updateOrderInfoFinishState(yxBankerOrders.get(0).getId(), 0);
        }
        log.info("====结束更新订单为已发货：" + yxOrder.getChildOrderNo());
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateOrderReturnGoodStatus(List<String> childOrderNoList) {
        bankerOrderMapper.updateOrderReturnGoodStatus(childOrderNoList);
        ordersMapper.updateOrderReturnGoodStatus(childOrderNoList);
    }
}

